Adding compact layout (#2991)
* Adding compact layout * Fixing ESLint error
Этот коммит содержится в:
коммит произвёл
Christopher Speller
родитель
565b111234
Коммит
0258fcfa5c
@@ -8,6 +8,7 @@ import Client from 'utils/web_client.jsx';
|
|||||||
import Constants from 'utils/constants.jsx';
|
import Constants from 'utils/constants.jsx';
|
||||||
|
|
||||||
import {intlShape, injectIntl, defineMessages} from 'react-intl';
|
import {intlShape, injectIntl, defineMessages} from 'react-intl';
|
||||||
|
import {Tooltip, OverlayTrigger} from 'react-bootstrap';
|
||||||
|
|
||||||
const holders = defineMessages({
|
const holders = defineMessages({
|
||||||
download: {
|
download: {
|
||||||
@@ -169,6 +170,42 @@ class FileAttachment extends React.Component {
|
|||||||
} else {
|
} else {
|
||||||
trimmedFilename = filenameString;
|
trimmedFilename = filenameString;
|
||||||
}
|
}
|
||||||
|
var filenameOverlay = (
|
||||||
|
<OverlayTrigger
|
||||||
|
delayShow={1000}
|
||||||
|
placement='top'
|
||||||
|
overlay={<Tooltip id='file-name__tooltip'>{this.props.intl.formatMessage(holders.download) + ' "' + filenameString + '"'}</Tooltip>}
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
href={fileUrl}
|
||||||
|
download={filenameString}
|
||||||
|
className='post-image__name'
|
||||||
|
target='_blank'
|
||||||
|
rel='noopener noreferrer'
|
||||||
|
>
|
||||||
|
{trimmedFilename}
|
||||||
|
</a>
|
||||||
|
</OverlayTrigger>
|
||||||
|
);
|
||||||
|
|
||||||
|
if (this.props.compactDisplay) {
|
||||||
|
filenameOverlay = (
|
||||||
|
<OverlayTrigger
|
||||||
|
delayShow={1000}
|
||||||
|
placement='top'
|
||||||
|
overlay={<Tooltip id='file-name__tooltip'>{filenameString}</Tooltip>}
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
href='#'
|
||||||
|
onClick={() => this.props.handleImageClick(this.props.index)}
|
||||||
|
className='post-image__name'
|
||||||
|
rel='noopener noreferrer'
|
||||||
|
>
|
||||||
|
<i className='glyphicon glyphicon-paperclip'/>{trimmedFilename}
|
||||||
|
</a>
|
||||||
|
</OverlayTrigger>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@@ -183,17 +220,7 @@ class FileAttachment extends React.Component {
|
|||||||
{thumbnail}
|
{thumbnail}
|
||||||
</a>
|
</a>
|
||||||
<div className='post-image__details'>
|
<div className='post-image__details'>
|
||||||
<a
|
{filenameOverlay}
|
||||||
href={fileUrl}
|
|
||||||
download={filenameString}
|
|
||||||
data-toggle='tooltip'
|
|
||||||
title={this.props.intl.formatMessage(holders.download) + ' "' + filenameString + '"'}
|
|
||||||
className='post-image__name'
|
|
||||||
target='_blank'
|
|
||||||
rel='noopener noreferrer'
|
|
||||||
>
|
|
||||||
{trimmedFilename}
|
|
||||||
</a>
|
|
||||||
<div>
|
<div>
|
||||||
<a
|
<a
|
||||||
href={fileUrl}
|
href={fileUrl}
|
||||||
@@ -225,7 +252,9 @@ FileAttachment.propTypes = {
|
|||||||
index: React.PropTypes.number.isRequired,
|
index: React.PropTypes.number.isRequired,
|
||||||
|
|
||||||
// handler for when the thumbnail is clicked passed the index above
|
// handler for when the thumbnail is clicked passed the index above
|
||||||
handleImageClick: React.PropTypes.func
|
handleImageClick: React.PropTypes.func,
|
||||||
|
|
||||||
|
compactDisplay: React.PropTypes.bool
|
||||||
};
|
};
|
||||||
|
|
||||||
export default injectIntl(FileAttachment);
|
export default injectIntl(FileAttachment);
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ export default class FileAttachmentList extends React.Component {
|
|||||||
filename={filenames[i]}
|
filename={filenames[i]}
|
||||||
index={i}
|
index={i}
|
||||||
handleImageClick={this.handleImageClick}
|
handleImageClick={this.handleImageClick}
|
||||||
|
compactDisplay={this.props.compactDisplay}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -60,5 +61,7 @@ FileAttachmentList.propTypes = {
|
|||||||
channelId: React.PropTypes.string,
|
channelId: React.PropTypes.string,
|
||||||
|
|
||||||
// the user that owns the post that this is attached to
|
// the user that owns the post that this is attached to
|
||||||
userId: React.PropTypes.string
|
userId: React.PropTypes.string,
|
||||||
|
|
||||||
|
compactDisplay: React.PropTypes.bool
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -103,6 +103,10 @@ export default class Post extends React.Component {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nextProps.compactDisplay !== this.props.compactDisplay) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!Utils.areObjectsEqual(nextProps.user, this.props.user)) {
|
if (!Utils.areObjectsEqual(nextProps.user, this.props.user)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -188,7 +192,7 @@ export default class Post extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let profilePic = null;
|
let profilePic = null;
|
||||||
if (!this.props.hideProfilePic) {
|
if (!this.props.hideProfilePic || this.props.compactDisplay) {
|
||||||
profilePic = (
|
profilePic = (
|
||||||
<img
|
<img
|
||||||
src={Utils.getProfilePicSrcForPost(post, timestamp)}
|
src={Utils.getProfilePicSrcForPost(post, timestamp)}
|
||||||
@@ -212,11 +216,16 @@ export default class Post extends React.Component {
|
|||||||
centerClass = 'center';
|
centerClass = 'center';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let compactClass = '';
|
||||||
|
if (this.props.compactDisplay) {
|
||||||
|
compactClass = 'post--compact';
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
id={'post_' + post.id}
|
id={'post_' + post.id}
|
||||||
className={'post ' + sameUserClass + ' ' + rootUser + ' ' + postType + ' ' + currentUserCss + ' ' + shouldHighlightClass + ' ' + systemMessageClass}
|
className={'post ' + sameUserClass + ' ' + compactClass + ' ' + rootUser + ' ' + postType + ' ' + currentUserCss + ' ' + shouldHighlightClass + ' ' + systemMessageClass}
|
||||||
>
|
>
|
||||||
<div className={'post__content ' + centerClass}>
|
<div className={'post__content ' + centerClass}>
|
||||||
<div className='post__img'>{profilePic}</div>
|
<div className='post__img'>{profilePic}</div>
|
||||||
@@ -231,6 +240,7 @@ export default class Post extends React.Component {
|
|||||||
sameUser={this.props.sameUser}
|
sameUser={this.props.sameUser}
|
||||||
user={this.props.user}
|
user={this.props.user}
|
||||||
currentUser={this.props.currentUser}
|
currentUser={this.props.currentUser}
|
||||||
|
compactDisplay={this.props.compactDisplay}
|
||||||
/>
|
/>
|
||||||
<PostBody
|
<PostBody
|
||||||
post={post}
|
post={post}
|
||||||
@@ -239,6 +249,7 @@ export default class Post extends React.Component {
|
|||||||
posts={posts}
|
posts={posts}
|
||||||
handleCommentClick={this.handleCommentClick}
|
handleCommentClick={this.handleCommentClick}
|
||||||
retryPost={this.retryPost}
|
retryPost={this.retryPost}
|
||||||
|
compactDisplay={this.props.compactDisplay}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -261,5 +272,6 @@ Post.propTypes = {
|
|||||||
displayNameType: React.PropTypes.string,
|
displayNameType: React.PropTypes.string,
|
||||||
hasProfiles: React.PropTypes.bool,
|
hasProfiles: React.PropTypes.bool,
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
currentUser: React.PropTypes.object.isRequired,
|
||||||
center: React.PropTypes.bool
|
center: React.PropTypes.bool,
|
||||||
|
compactDisplay: React.PropTypes.bool
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,6 +24,10 @@ export default class PostBody extends React.Component {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!Utils.areObjectsEqual(nextProps.compactDisplay, this.props.compactDisplay)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (nextProps.retryPost.toString() !== this.props.retryPost.toString()) {
|
if (nextProps.retryPost.toString() !== this.props.retryPost.toString()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -136,9 +140,11 @@ export default class PostBody extends React.Component {
|
|||||||
if (filenames && filenames.length > 0) {
|
if (filenames && filenames.length > 0) {
|
||||||
fileAttachmentHolder = (
|
fileAttachmentHolder = (
|
||||||
<FileAttachmentList
|
<FileAttachmentList
|
||||||
|
|
||||||
filenames={filenames}
|
filenames={filenames}
|
||||||
channelId={post.channel_id}
|
channelId={post.channel_id}
|
||||||
userId={post.user_id}
|
userId={post.user_id}
|
||||||
|
compactDisplay={this.props.compactDisplay}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -189,5 +195,6 @@ PostBody.propTypes = {
|
|||||||
post: React.PropTypes.object.isRequired,
|
post: React.PropTypes.object.isRequired,
|
||||||
parentPost: React.PropTypes.object,
|
parentPost: React.PropTypes.object,
|
||||||
retryPost: React.PropTypes.func.isRequired,
|
retryPost: React.PropTypes.func.isRequired,
|
||||||
handleCommentClick: React.PropTypes.func.isRequired
|
handleCommentClick: React.PropTypes.func.isRequired,
|
||||||
|
compactDisplay: React.PropTypes.bool
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ export default class PostHeader extends React.Component {
|
|||||||
super(props);
|
super(props);
|
||||||
this.state = {};
|
this.state = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const post = this.props.post;
|
const post = this.props.post;
|
||||||
|
|
||||||
@@ -56,6 +57,7 @@ export default class PostHeader extends React.Component {
|
|||||||
isLastComment={this.props.isLastComment}
|
isLastComment={this.props.isLastComment}
|
||||||
sameUser={this.props.sameUser}
|
sameUser={this.props.sameUser}
|
||||||
currentUser={this.props.currentUser}
|
currentUser={this.props.currentUser}
|
||||||
|
compactDisplay={this.props.compactDisplay}
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -76,5 +78,6 @@ PostHeader.propTypes = {
|
|||||||
commentCount: React.PropTypes.number.isRequired,
|
commentCount: React.PropTypes.number.isRequired,
|
||||||
isLastComment: React.PropTypes.bool.isRequired,
|
isLastComment: React.PropTypes.bool.isRequired,
|
||||||
handleCommentClick: React.PropTypes.func.isRequired,
|
handleCommentClick: React.PropTypes.func.isRequired,
|
||||||
sameUser: React.PropTypes.bool.isRequired
|
sameUser: React.PropTypes.bool.isRequired,
|
||||||
|
compactDisplay: React.PropTypes.bool
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -219,6 +219,7 @@ export default class PostInfo extends React.Component {
|
|||||||
<TimeSince
|
<TimeSince
|
||||||
eventTime={post.create_at}
|
eventTime={post.create_at}
|
||||||
sameUser={this.props.sameUser}
|
sameUser={this.props.sameUser}
|
||||||
|
compactDisplay={this.props.compactDisplay}
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
<li className='col col__reply'>
|
<li className='col col__reply'>
|
||||||
@@ -250,5 +251,6 @@ PostInfo.propTypes = {
|
|||||||
allowReply: React.PropTypes.string.isRequired,
|
allowReply: React.PropTypes.string.isRequired,
|
||||||
handleCommentClick: React.PropTypes.func.isRequired,
|
handleCommentClick: React.PropTypes.func.isRequired,
|
||||||
sameUser: React.PropTypes.bool.isRequired,
|
sameUser: React.PropTypes.bool.isRequired,
|
||||||
currentUser: React.PropTypes.object.isRequired
|
currentUser: React.PropTypes.object.isRequired,
|
||||||
|
compactDisplay: React.PropTypes.bool
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ export default class PostsView extends React.Component {
|
|||||||
this.state = {
|
this.state = {
|
||||||
displayNameType: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', 'false'),
|
displayNameType: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', 'false'),
|
||||||
centerPosts: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.CHANNEL_DISPLAY_MODE, Preferences.CHANNEL_DISPLAY_MODE_DEFAULT) === Preferences.CHANNEL_DISPLAY_MODE_CENTERED,
|
centerPosts: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.CHANNEL_DISPLAY_MODE, Preferences.CHANNEL_DISPLAY_MODE_DEFAULT) === Preferences.CHANNEL_DISPLAY_MODE_CENTERED,
|
||||||
|
compactPosts: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.MESSAGE_DISPLAY, Preferences.MESSAGE_DISPLAY_DEFAULT) === Preferences.MESSAGE_DISPLAY_COMPACT,
|
||||||
isScrolling: false,
|
isScrolling: false,
|
||||||
topPostId: null,
|
topPostId: null,
|
||||||
currentUser: UserStore.getCurrentUser(),
|
currentUser: UserStore.getCurrentUser(),
|
||||||
@@ -79,7 +80,8 @@ export default class PostsView extends React.Component {
|
|||||||
updateState() {
|
updateState() {
|
||||||
this.setState({
|
this.setState({
|
||||||
displayNameType: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', 'false'),
|
displayNameType: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', 'false'),
|
||||||
centerPosts: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.CHANNEL_DISPLAY_MODE, Preferences.CHANNEL_DISPLAY_MODE_DEFAULT) === Preferences.CHANNEL_DISPLAY_MODE_CENTERED
|
centerPosts: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.CHANNEL_DISPLAY_MODE, Preferences.CHANNEL_DISPLAY_MODE_DEFAULT) === Preferences.CHANNEL_DISPLAY_MODE_CENTERED,
|
||||||
|
compactPosts: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.MESSAGE_DISPLAY, Preferences.MESSAGE_DISPLAY_DEFAULT) === Preferences.MESSAGE_DISPLAY_COMPACT
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
onUserChange() {
|
onUserChange() {
|
||||||
@@ -274,6 +276,7 @@ export default class PostsView extends React.Component {
|
|||||||
user={profile}
|
user={profile}
|
||||||
currentUser={this.state.currentUser}
|
currentUser={this.state.currentUser}
|
||||||
center={this.state.centerPosts}
|
center={this.state.centerPosts}
|
||||||
|
compactDisplay={this.state.compactPosts}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -479,6 +482,9 @@ export default class PostsView extends React.Component {
|
|||||||
if (this.state.centerPosts !== nextState.centerPosts) {
|
if (this.state.centerPosts !== nextState.centerPosts) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (this.state.compactPosts !== nextState.compactPosts) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (!Utils.areObjectsEqual(this.state.profiles, nextState.profiles)) {
|
if (!Utils.areObjectsEqual(this.state.profiles, nextState.profiles)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -592,7 +598,8 @@ PostsView.propTypes = {
|
|||||||
showMoreMessagesBottom: React.PropTypes.bool,
|
showMoreMessagesBottom: React.PropTypes.bool,
|
||||||
channel: React.PropTypes.object,
|
channel: React.PropTypes.object,
|
||||||
messageSeparatorTime: React.PropTypes.number,
|
messageSeparatorTime: React.PropTypes.number,
|
||||||
postsToHighlight: React.PropTypes.object
|
postsToHighlight: React.PropTypes.object,
|
||||||
|
compactDisplay: React.PropTypes.bool
|
||||||
};
|
};
|
||||||
|
|
||||||
function ScrollToBottomArrows({isScrolling, atBottom, onClick}) {
|
function ScrollToBottomArrows({isScrolling, atBottom, onClick}) {
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export default class TimeSince extends React.Component {
|
|||||||
clearInterval(this.intervalId);
|
clearInterval(this.intervalId);
|
||||||
}
|
}
|
||||||
render() {
|
render() {
|
||||||
if (this.props.sameUser) {
|
if (this.props.sameUser || this.props.compactDisplay) {
|
||||||
return (
|
return (
|
||||||
<time className='post__time'>
|
<time className='post__time'>
|
||||||
{Utils.displayTimeFormatted(this.props.eventTime)}
|
{Utils.displayTimeFormatted(this.props.eventTime)}
|
||||||
@@ -69,5 +69,6 @@ TimeSince.defaultProps = {
|
|||||||
|
|
||||||
TimeSince.propTypes = {
|
TimeSince.propTypes = {
|
||||||
eventTime: React.PropTypes.number.isRequired,
|
eventTime: React.PropTypes.number.isRequired,
|
||||||
sameUser: React.PropTypes.bool
|
sameUser: React.PropTypes.bool,
|
||||||
|
compactDisplay: React.PropTypes.bool
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ function getDisplayStateFromStores() {
|
|||||||
militaryTime: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'use_military_time', 'false'),
|
militaryTime: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'use_military_time', 'false'),
|
||||||
nameFormat: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', 'username'),
|
nameFormat: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', 'username'),
|
||||||
selectedFont: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'selected_font', Constants.DEFAULT_FONT),
|
selectedFont: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'selected_font', Constants.DEFAULT_FONT),
|
||||||
channelDisplayMode: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.CHANNEL_DISPLAY_MODE, Preferences.CHANNEL_DISPLAY_MODE_DEFAULT)
|
channelDisplayMode: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.CHANNEL_DISPLAY_MODE, Preferences.CHANNEL_DISPLAY_MODE_DEFAULT),
|
||||||
|
messageDisplay: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.MESSAGE_DISPLAY, Preferences.MESSAGE_DISPLAY_DEFAULT)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,8 +71,14 @@ export default class UserSettingsDisplay extends React.Component {
|
|||||||
name: Preferences.CHANNEL_DISPLAY_MODE,
|
name: Preferences.CHANNEL_DISPLAY_MODE,
|
||||||
value: this.state.channelDisplayMode
|
value: this.state.channelDisplayMode
|
||||||
};
|
};
|
||||||
|
const messageDisplayPreference = {
|
||||||
|
user_id: userId,
|
||||||
|
category: Preferences.CATEGORY_DISPLAY_SETTINGS,
|
||||||
|
name: Preferences.MESSAGE_DISPLAY,
|
||||||
|
value: this.state.messageDisplay
|
||||||
|
};
|
||||||
|
|
||||||
AsyncClient.savePreferences([timePreference, namePreference, fontPreference, channelDisplayModePreference],
|
AsyncClient.savePreferences([timePreference, namePreference, fontPreference, channelDisplayModePreference, messageDisplayPreference],
|
||||||
() => {
|
() => {
|
||||||
this.updateSection('');
|
this.updateSection('');
|
||||||
},
|
},
|
||||||
@@ -89,6 +96,9 @@ export default class UserSettingsDisplay extends React.Component {
|
|||||||
handleChannelDisplayModeRadio(channelDisplayMode) {
|
handleChannelDisplayModeRadio(channelDisplayMode) {
|
||||||
this.setState({channelDisplayMode});
|
this.setState({channelDisplayMode});
|
||||||
}
|
}
|
||||||
|
handlemessageDisplayRadio(messageDisplay) {
|
||||||
|
this.setState({messageDisplay});
|
||||||
|
}
|
||||||
handleFont(selectedFont) {
|
handleFont(selectedFont) {
|
||||||
Utils.applyFont(selectedFont);
|
Utils.applyFont(selectedFont);
|
||||||
this.setState({selectedFont});
|
this.setState({selectedFont});
|
||||||
@@ -115,6 +125,7 @@ export default class UserSettingsDisplay extends React.Component {
|
|||||||
let channelDisplayModeSection;
|
let channelDisplayModeSection;
|
||||||
let fontSection;
|
let fontSection;
|
||||||
let languagesSection;
|
let languagesSection;
|
||||||
|
let messageDisplaySection;
|
||||||
|
|
||||||
if (this.props.activeSection === 'clock') {
|
if (this.props.activeSection === 'clock') {
|
||||||
const clockFormat = [false, false];
|
const clockFormat = [false, false];
|
||||||
@@ -350,6 +361,105 @@ export default class UserSettingsDisplay extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.props.activeSection === Preferences.MESSAGE_DISPLAY) {
|
||||||
|
const messageDisplay = [false, false];
|
||||||
|
if (this.state.messageDisplay === Preferences.MESSAGE_DISPLAY_CLEAN) {
|
||||||
|
messageDisplay[0] = true;
|
||||||
|
} else {
|
||||||
|
messageDisplay[1] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const inputs = [
|
||||||
|
<div key='userDisplayNameOptions'>
|
||||||
|
<div className='radio'>
|
||||||
|
<label>
|
||||||
|
<input
|
||||||
|
type='radio'
|
||||||
|
checked={messageDisplay[0]}
|
||||||
|
onChange={this.handlemessageDisplayRadio.bind(this, Preferences.MESSAGE_DISPLAY_CLEAN)}
|
||||||
|
/>
|
||||||
|
<FormattedMessage
|
||||||
|
id='user.settings.display.messageDisplayClean'
|
||||||
|
defaultMessage='Clean'
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<br/>
|
||||||
|
</div>
|
||||||
|
<div className='radio'>
|
||||||
|
<label>
|
||||||
|
<input
|
||||||
|
type='radio'
|
||||||
|
checked={messageDisplay[1]}
|
||||||
|
onChange={this.handlemessageDisplayRadio.bind(this, Preferences.MESSAGE_DISPLAY_COMPACT)}
|
||||||
|
/>
|
||||||
|
<FormattedMessage
|
||||||
|
id='user.settings.display.messageDisplayCompact'
|
||||||
|
defaultMessage='Compact'
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<br/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<br/>
|
||||||
|
<FormattedMessage
|
||||||
|
id='user.settings.display.messageDisplayDescription'
|
||||||
|
defaultMessage='Select how messages in a channel should be displayed.'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
];
|
||||||
|
|
||||||
|
messageDisplaySection = (
|
||||||
|
<SettingItemMax
|
||||||
|
title={
|
||||||
|
<FormattedMessage
|
||||||
|
id='user.settings.display.messageDisplayTitle'
|
||||||
|
defaultMessage='Message Display'
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
inputs={inputs}
|
||||||
|
submit={this.handleSubmit}
|
||||||
|
server_error={serverError}
|
||||||
|
updateSection={(e) => {
|
||||||
|
this.updateSection('');
|
||||||
|
e.preventDefault();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
let describe;
|
||||||
|
if (this.state.messageDisplay === Preferences.MESSAGE_DISPLAY_CLEAN) {
|
||||||
|
describe = (
|
||||||
|
<FormattedMessage
|
||||||
|
id='user.settings.display.messageDisplayClean'
|
||||||
|
defaultMessage='Clean'
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
describe = (
|
||||||
|
<FormattedMessage
|
||||||
|
id='user.settings.display.messageDisplayCompact'
|
||||||
|
defaultMessage='Compact'
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
messageDisplaySection = (
|
||||||
|
<SettingItemMin
|
||||||
|
title={
|
||||||
|
<FormattedMessage
|
||||||
|
id='user.settings.display.messageDisplayTitle'
|
||||||
|
defaultMessage='Message Display'
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
describe={describe}
|
||||||
|
updateSection={() => {
|
||||||
|
this.props.updateSection(Preferences.MESSAGE_DISPLAY);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (this.props.activeSection === Preferences.CHANNEL_DISPLAY_MODE) {
|
if (this.props.activeSection === Preferences.CHANNEL_DISPLAY_MODE) {
|
||||||
const channelDisplayMode = [false, false];
|
const channelDisplayMode = [false, false];
|
||||||
if (this.state.channelDisplayMode === Preferences.CHANNEL_DISPLAY_MODE_CENTERED) {
|
if (this.state.channelDisplayMode === Preferences.CHANNEL_DISPLAY_MODE_CENTERED) {
|
||||||
@@ -392,7 +502,7 @@ export default class UserSettingsDisplay extends React.Component {
|
|||||||
<br/>
|
<br/>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='user.settings.display.channeldisplaymode'
|
id='user.settings.display.channeldisplaymode'
|
||||||
defaultMessage='Select how text in a channel is displayed.'
|
defaultMessage='Select the width of the center channel.'
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -601,6 +711,8 @@ export default class UserSettingsDisplay extends React.Component {
|
|||||||
<div className='divider-dark'/>
|
<div className='divider-dark'/>
|
||||||
{nameFormatSection}
|
{nameFormatSection}
|
||||||
<div className='divider-dark'/>
|
<div className='divider-dark'/>
|
||||||
|
{messageDisplaySection}
|
||||||
|
<div className='divider-dark'/>
|
||||||
{channelDisplayModeSection}
|
{channelDisplayModeSection}
|
||||||
<div className='divider-dark'/>
|
<div className='divider-dark'/>
|
||||||
{languagesSection}
|
{languagesSection}
|
||||||
|
|||||||
@@ -1288,9 +1288,13 @@
|
|||||||
"user.settings.developer.thirdParty": "Open to register a new third-party application",
|
"user.settings.developer.thirdParty": "Open to register a new third-party application",
|
||||||
"user.settings.developer.title": "Developer Settings",
|
"user.settings.developer.title": "Developer Settings",
|
||||||
"user.settings.display.channelDisplayTitle": "Channel Display Mode",
|
"user.settings.display.channelDisplayTitle": "Channel Display Mode",
|
||||||
"user.settings.display.channeldisplaymode": "Select how text in a channel is displayed.",
|
"user.settings.display.channeldisplaymode": "Select the width of the center channel.",
|
||||||
"user.settings.display.clockDisplay": "Clock Display",
|
"user.settings.display.clockDisplay": "Clock Display",
|
||||||
"user.settings.display.fixedWidthCentered": "Fixed width, centered",
|
"user.settings.display.fixedWidthCentered": "Fixed width, centered",
|
||||||
|
"user.settings.display.messageDisplayTitle": "Message Display",
|
||||||
|
"user.settings.display.messageDisplayDescription": "Select how messages in a channel should be displayed.",
|
||||||
|
"user.settings.display.messageDisplayClean": "Clean",
|
||||||
|
"user.settings.display.messageDisplayCompact": "Compact",
|
||||||
"user.settings.display.fontDesc": "Select the font displayed in the Mattermost user interface.",
|
"user.settings.display.fontDesc": "Select the font displayed in the Mattermost user interface.",
|
||||||
"user.settings.display.fontTitle": "Display Font",
|
"user.settings.display.fontTitle": "Display Font",
|
||||||
"user.settings.display.fullScreen": "Full width",
|
"user.settings.display.fullScreen": "Full width",
|
||||||
|
|||||||
@@ -448,7 +448,7 @@
|
|||||||
@include opacity(.8);
|
@include opacity(.8);
|
||||||
float: right;
|
float: right;
|
||||||
margin-right: 3px;
|
margin-right: 3px;
|
||||||
margin-top: 12px;
|
margin-top: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.member-select__container {
|
.member-select__container {
|
||||||
@@ -459,7 +459,7 @@
|
|||||||
select {
|
select {
|
||||||
@include opacity(.8);
|
@include opacity(.8);
|
||||||
float: right;
|
float: right;
|
||||||
margin: 5px 5px 0 2px;
|
margin: 1px 5px 0 2px;
|
||||||
width: auto;
|
width: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -417,7 +417,8 @@ body.ios {
|
|||||||
.post-create-footer {
|
.post-create-footer {
|
||||||
@include clearfix;
|
@include clearfix;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
padding: 3px 0 0 0;
|
padding: 3px 0 0;
|
||||||
|
|
||||||
.control-label {
|
.control-label {
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
@@ -482,6 +483,79 @@ body.ios {
|
|||||||
background-color: beige;
|
background-color: beige;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.post--compact {
|
||||||
|
|
||||||
|
.markdown__heading {
|
||||||
|
font-size: 1em;
|
||||||
|
margin: 0 0 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post__body {
|
||||||
|
background: transparent !important;
|
||||||
|
margin-top: -1px;
|
||||||
|
padding: 3px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-image__columns {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-image__column {
|
||||||
|
@include border-radius(2px);
|
||||||
|
font-size: .9em;
|
||||||
|
height: 26px;
|
||||||
|
line-height: 25px;
|
||||||
|
padding: 0 7px;
|
||||||
|
|
||||||
|
.post-image__thumbnail {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-image__details {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
> div {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-image__name {
|
||||||
|
@include clearfix;
|
||||||
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
padding-right: 10px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: .9em;
|
||||||
|
margin-right: 5px;
|
||||||
|
opacity: .5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
&:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.post__img {
|
||||||
|
padding-top: 3px;
|
||||||
|
width: 28px;
|
||||||
|
|
||||||
|
img,
|
||||||
|
svg {
|
||||||
|
height: 20px;
|
||||||
|
width: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
font-size: .97em;
|
font-size: .97em;
|
||||||
line-height: 1.6em;
|
line-height: 1.6em;
|
||||||
|
|||||||
@@ -45,6 +45,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.post {
|
.post {
|
||||||
|
&.post--compact {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
.post__dropdown {
|
.post__dropdown {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
|
|||||||
@@ -65,6 +65,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tablet and desktop
|
||||||
@media screen and (min-width: 768px) {
|
@media screen and (min-width: 768px) {
|
||||||
.second-bar {
|
.second-bar {
|
||||||
display: none;
|
display: none;
|
||||||
@@ -83,6 +84,111 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.post {
|
.post {
|
||||||
|
&.post--compact {
|
||||||
|
padding: 5px .5em 0 80px;
|
||||||
|
|
||||||
|
.post__link {
|
||||||
|
margin: 4px 0 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post__time {
|
||||||
|
font-size: .85em;
|
||||||
|
left: -70px;
|
||||||
|
position: absolute;
|
||||||
|
top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
p {
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: .3em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.post__header {
|
||||||
|
float: left;
|
||||||
|
height: 18px;
|
||||||
|
padding-top: 3px;
|
||||||
|
|
||||||
|
.col__name {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col__reply {
|
||||||
|
top: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.other--root {
|
||||||
|
.post__body {
|
||||||
|
> div {
|
||||||
|
&:first-child {
|
||||||
|
min-height: 21px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.post__link + .post__body {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.post--comment {
|
||||||
|
.post__header {
|
||||||
|
.col__reply {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-code {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.same--root {
|
||||||
|
&.same--user {
|
||||||
|
padding-left: 80px;
|
||||||
|
|
||||||
|
.post__img {
|
||||||
|
img {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.post--comment {
|
||||||
|
padding-top: 1px;
|
||||||
|
|
||||||
|
.post__img {
|
||||||
|
img {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.same--user {
|
||||||
|
.post__img {
|
||||||
|
img {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.post__header {
|
||||||
|
margin-left: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.post__body {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post__content {
|
||||||
|
padding-right: 85px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.same--root {
|
&.same--root {
|
||||||
&.same--user {
|
&.same--user {
|
||||||
.post__time {
|
.post__time {
|
||||||
@@ -94,6 +200,14 @@
|
|||||||
text-rendering: auto;
|
text-rendering: auto;
|
||||||
top: -2px;
|
top: -2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.post--compact {
|
||||||
|
.post__time {
|
||||||
|
font-size: .85em;
|
||||||
|
left: -70px;
|
||||||
|
top: -5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -531,7 +531,11 @@ export default {
|
|||||||
CHANNEL_DISPLAY_MODE: 'channel_display_mode',
|
CHANNEL_DISPLAY_MODE: 'channel_display_mode',
|
||||||
CHANNEL_DISPLAY_MODE_CENTERED: 'centered',
|
CHANNEL_DISPLAY_MODE_CENTERED: 'centered',
|
||||||
CHANNEL_DISPLAY_MODE_FULL_SCREEN: 'full',
|
CHANNEL_DISPLAY_MODE_FULL_SCREEN: 'full',
|
||||||
CHANNEL_DISPLAY_MODE_DEFAULT: 'centered'
|
CHANNEL_DISPLAY_MODE_DEFAULT: 'centered',
|
||||||
|
MESSAGE_DISPLAY: 'message_display',
|
||||||
|
MESSAGE_DISPLAY_CLEAN: 'clean',
|
||||||
|
MESSAGE_DISPLAY_COMPACT: 'compact',
|
||||||
|
MESSAGE_DISPLAY_DEFAULT: 'clean'
|
||||||
},
|
},
|
||||||
TutorialSteps: {
|
TutorialSteps: {
|
||||||
INTRO_SCREENS: 0,
|
INTRO_SCREENS: 0,
|
||||||
|
|||||||
@@ -734,7 +734,7 @@ export function applyTheme(theme) {
|
|||||||
changeCss('.app__body .scrollbar--horizontal, .app__body .scrollbar--vertical', 'background:' + changeOpacity(theme.centerChannelColor, 0.5), 2);
|
changeCss('.app__body .scrollbar--horizontal, .app__body .scrollbar--vertical', 'background:' + changeOpacity(theme.centerChannelColor, 0.5), 2);
|
||||||
changeCss('.app__body .post-list__new-messages-below', 'background:' + changeColor(theme.centerChannelColor, 0.5), 2);
|
changeCss('.app__body .post-list__new-messages-below', 'background:' + changeColor(theme.centerChannelColor, 0.5), 2);
|
||||||
changeCss('.app__body .post.post--comment .post__body', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2), 1);
|
changeCss('.app__body .post.post--comment .post__body', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2), 1);
|
||||||
changeCss('.app__body .post.post--comment.current--user .post__body', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.13), 1);
|
changeCss('.app__body .post.post--comment.current--user .post__body', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (theme.newMessageSeparator) {
|
if (theme.newMessageSeparator) {
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user