PLT-3182 - Improving switch channels modal and some minor UI improvements (#3238)

* PLT-3182 - Improving switch channels modal and some minor UI improvements

Enabling link previews

Adding compact layout to RHS

Improving timestamps

* Adding update code for RHS components
Этот коммит содержится в:
Asaad Mahmood
2016-06-06 17:46:03 +05:00
коммит произвёл Joram Wilander
родитель 53a35f2f8e
Коммит 353216e05c
13 изменённых файлов: 267 добавлений и 193 удалений

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

@@ -98,10 +98,12 @@ export default class SwitchChannelModal extends React.Component {
</Modal.Header> </Modal.Header>
<Modal.Body> <Modal.Body>
<FormattedMessage <div className='modal__hint'>
id='channel_switch_modal.help' <FormattedMessage
defaultMessage='↑↓ to browse, TAB to select, ↵ to confirm, ESC to dismiss' id='channel_switch_modal.help'
/> defaultMessage='↑↓ to browse, TAB to select, ↵ to confirm, ESC to dismiss'
/>
</div>
<SuggestionBox <SuggestionBox
ref='search' ref='search'
className='form-control focused' className='form-control focused'
@@ -118,9 +120,9 @@ export default class SwitchChannelModal extends React.Component {
/> />
</Modal.Body> </Modal.Body>
<Modal.Footer> <Modal.Footer>
<label className='control-label'> <div className='modal__error'>
{message} {message}
</label> </div>
<button <button
type='button' type='button'
className='btn btn-default' className='btn btn-default'

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

@@ -97,18 +97,16 @@ export default class PostBodyAdditionalContent extends React.Component {
); );
} }
if (!this.props.compactDisplay) { for (let i = 0; i < Constants.IMAGE_TYPES.length; i++) {
for (let i = 0; i < Constants.IMAGE_TYPES.length; i++) { const imageType = Constants.IMAGE_TYPES[i];
const imageType = Constants.IMAGE_TYPES[i]; const suffix = link.substring(link.length - (imageType.length + 1));
const suffix = link.substring(link.length - (imageType.length + 1)); if (suffix === '.' + imageType || suffix === '=' + imageType) {
if (suffix === '.' + imageType || suffix === '=' + imageType) { return (
return ( <PostImage
<PostImage channelId={this.props.post.channel_id}
channelId={this.props.post.channel_id} link={link}
link={link} />
/> );
);
}
} }
} }

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

@@ -35,6 +35,9 @@ export default class RhsComment extends React.Component {
GlobalActions.showGetPostLinkModal(this.props.post); GlobalActions.showGetPostLinkModal(this.props.post);
} }
shouldComponentUpdate(nextProps) { shouldComponentUpdate(nextProps) {
if (nextProps.compactDisplay !== this.props.compactDisplay) {
return true;
}
if (!Utils.areObjectsEqual(nextProps.post, this.props.post)) { if (!Utils.areObjectsEqual(nextProps.post, this.props.post)) {
return true; return true;
} }
@@ -186,6 +189,11 @@ export default class RhsComment extends React.Component {
); );
} }
let compactClass = '';
if (this.props.compactDisplay) {
compactClass = 'post--compact';
}
var dropdown = this.createDropdown(); var dropdown = this.createDropdown();
var fileAttachment; var fileAttachment;
@@ -195,12 +203,13 @@ export default class RhsComment extends React.Component {
filenames={post.filenames} filenames={post.filenames}
channelId={post.channel_id} channelId={post.channel_id}
userId={post.user_id} userId={post.user_id}
compactDisplay={this.props.compactDisplay}
/> />
); );
} }
return ( return (
<div className={'post ' + currentUserCss}> <div className={'post post--thread ' + currentUserCss + ' ' + compactClass}>
<div className='post__content'> <div className='post__content'>
<div className='post__img'> <div className='post__img'>
<img <img
@@ -249,5 +258,6 @@ export default class RhsComment extends React.Component {
RhsComment.propTypes = { RhsComment.propTypes = {
post: React.PropTypes.object, post: React.PropTypes.object,
user: React.PropTypes.object.isRequired, user: React.PropTypes.object.isRequired,
currentUser: React.PropTypes.object.isRequired currentUser: React.PropTypes.object.isRequired,
compactDisplay: React.PropTypes.bool
}; };

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

@@ -32,6 +32,9 @@ export default class RhsRootPost extends React.Component {
GlobalActions.showGetPostLinkModal(this.props.post); GlobalActions.showGetPostLinkModal(this.props.post);
} }
shouldComponentUpdate(nextProps) { shouldComponentUpdate(nextProps) {
if (nextProps.compactDisplay !== this.props.compactDisplay) {
return true;
}
if (!Utils.areObjectsEqual(nextProps.post, this.props.post)) { if (!Utils.areObjectsEqual(nextProps.post, this.props.post)) {
return true; return true;
} }
@@ -220,6 +223,11 @@ export default class RhsRootPost extends React.Component {
); );
} }
let compactClass = '';
if (this.props.compactDisplay) {
compactClass = 'post--compact';
}
const messageWrapper = ( const messageWrapper = (
<div <div
ref='message_holder' ref='message_holder'
@@ -229,7 +237,7 @@ export default class RhsRootPost extends React.Component {
); );
return ( return (
<div className={'post post--root ' + userCss + ' ' + systemMessageClass}> <div className={'post post--root post--thread ' + userCss + ' ' + systemMessageClass + ' ' + compactClass}>
<div className='post-right-channel__name'>{channelName}</div> <div className='post-right-channel__name'>{channelName}</div>
<div className='post__content'> <div className='post__content'>
<div className='post__img'> <div className='post__img'>
@@ -279,5 +287,6 @@ RhsRootPost.propTypes = {
post: React.PropTypes.object.isRequired, post: React.PropTypes.object.isRequired,
user: React.PropTypes.object.isRequired, user: React.PropTypes.object.isRequired,
currentUser: React.PropTypes.object.isRequired, currentUser: React.PropTypes.object.isRequired,
commentCount: React.PropTypes.number commentCount: React.PropTypes.number,
compactDisplay: React.PropTypes.bool
}; };

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

@@ -12,6 +12,7 @@ import RhsHeaderPost from './rhs_header_post.jsx';
import RootPost from './rhs_root_post.jsx'; import RootPost from './rhs_root_post.jsx';
import Comment from './rhs_comment.jsx'; import Comment from './rhs_comment.jsx';
import Constants from 'utils/constants.jsx'; import Constants from 'utils/constants.jsx';
const Preferences = Constants.Preferences;
import FileUploadOverlay from './file_upload_overlay.jsx'; import FileUploadOverlay from './file_upload_overlay.jsx';
import Scrollbars from 'react-custom-scrollbars'; import Scrollbars from 'react-custom-scrollbars';
@@ -50,12 +51,14 @@ export default class RhsThread extends React.Component {
this.onPostChange = this.onPostChange.bind(this); this.onPostChange = this.onPostChange.bind(this);
this.onUserChange = this.onUserChange.bind(this); this.onUserChange = this.onUserChange.bind(this);
this.forceUpdateInfo = this.forceUpdateInfo.bind(this); this.forceUpdateInfo = this.forceUpdateInfo.bind(this);
this.onPreferenceChange = this.onPreferenceChange.bind(this);
this.handleResize = this.handleResize.bind(this); this.handleResize = this.handleResize.bind(this);
const state = this.getPosts(); const state = this.getPosts();
state.windowWidth = Utils.windowWidth(); state.windowWidth = Utils.windowWidth();
state.windowHeight = Utils.windowHeight(); state.windowHeight = Utils.windowHeight();
state.profiles = JSON.parse(JSON.stringify(UserStore.getProfiles())); state.profiles = JSON.parse(JSON.stringify(UserStore.getProfiles()));
state.compactDisplay = PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.MESSAGE_DISPLAY, Preferences.MESSAGE_DISPLAY_DEFAULT) === Preferences.MESSAGE_DISPLAY_COMPACT;
this.state = state; this.state = state;
} }
@@ -63,6 +66,7 @@ export default class RhsThread extends React.Component {
PostStore.addSelectedPostChangeListener(this.onPostChange); PostStore.addSelectedPostChangeListener(this.onPostChange);
PostStore.addChangeListener(this.onPostChange); PostStore.addChangeListener(this.onPostChange);
PreferenceStore.addChangeListener(this.forceUpdateInfo); PreferenceStore.addChangeListener(this.forceUpdateInfo);
PreferenceStore.addChangeListener(this.onPreferenceChange);
UserStore.addChangeListener(this.onUserChange); UserStore.addChangeListener(this.onUserChange);
this.scrollToBottom(); this.scrollToBottom();
@@ -74,6 +78,7 @@ export default class RhsThread extends React.Component {
PostStore.removeSelectedPostChangeListener(this.onPostChange); PostStore.removeSelectedPostChangeListener(this.onPostChange);
PostStore.removeChangeListener(this.onPostChange); PostStore.removeChangeListener(this.onPostChange);
PreferenceStore.removeChangeListener(this.forceUpdateInfo); PreferenceStore.removeChangeListener(this.forceUpdateInfo);
PreferenceStore.removeChangeListener(this.onPreferenceChange);
UserStore.removeChangeListener(this.onUserChange); UserStore.removeChangeListener(this.onUserChange);
window.removeEventListener('resize', this.handleResize); window.removeEventListener('resize', this.handleResize);
@@ -103,6 +108,10 @@ export default class RhsThread extends React.Component {
return true; return true;
} }
if (nextState.compactDisplay !== this.state.compactDisplay) {
return true;
}
if (!Utils.areObjectsEqual(nextState.profiles, this.state.profiles)) { if (!Utils.areObjectsEqual(nextState.profiles, this.state.profiles)) {
return true; return true;
} }
@@ -124,6 +133,11 @@ export default class RhsThread extends React.Component {
windowHeight: Utils.windowHeight() windowHeight: Utils.windowHeight()
}); });
} }
onPreferenceChange() {
this.setState({
compactDisplay: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.MESSAGE_DISPLAY, Preferences.MESSAGE_DISPLAY_DEFAULT) === Preferences.MESSAGE_DISPLAY_COMPACT
});
}
onPostChange() { onPostChange() {
if (this.mounted) { if (this.mounted) {
this.setState(this.getPosts()); this.setState(this.getPosts());
@@ -228,6 +242,7 @@ export default class RhsThread extends React.Component {
commentCount={postsArray.length} commentCount={postsArray.length}
user={profile} user={profile}
currentUser={this.props.currentUser} currentUser={this.props.currentUser}
compactDisplay={this.state.compactDisplay}
/> />
<div className='post-right-comments-container'> <div className='post-right-comments-container'>
{postsArray.map((comPost) => { {postsArray.map((comPost) => {
@@ -244,6 +259,7 @@ export default class RhsThread extends React.Component {
post={comPost} post={comPost}
user={p} user={p}
currentUser={this.props.currentUser} currentUser={this.props.currentUser}
compactDisplay={this.state.compactDisplay}
/> />
); );
})} })}

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

@@ -29,6 +29,21 @@
} }
} }
.modal__hint {
@include opacity(.8);
display: block;
font-size: .9em;
margin: 0 0 10px;
}
.modal__error {
color: $red;
float: left;
font-size: .95em;
font-weight: normal;
margin-top: 6px;
}
.more-table { .more-table {
margin: 0; margin: 0;
table-layout: fixed; table-layout: fixed;

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

@@ -28,7 +28,7 @@
.post { .post {
&.post--root { &.post--root {
border-bottom: 1px solid #ddd; border-bottom: 1px solid #ddd;
padding-bottom: 1.2em; padding-bottom: 1em;
.post__body { .post__body {
background: transparent !important; background: transparent !important;

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

@@ -488,6 +488,13 @@ body.ios {
} }
&.post--compact { &.post--compact {
&.post--thread {
.post__header {
height: 22px;
padding-top: 3px;
}
}
blockquote { blockquote {
display: inline-block; display: inline-block;
font-size: 1em; font-size: 1em;
@@ -509,10 +516,19 @@ body.ios {
.post__body { .post__body {
background: transparent !important; background: transparent !important;
line-height: 1.2; line-height: 1.6;
margin-top: -1px; margin-top: -1px;
padding: 3px 0; padding: 3px 0;
.img-div {
max-height: 150px;
max-width: 150px;
}
p {
line-height: inherit;
}
p + p { p + p {
margin-top: 1em; margin-top: 1em;
} }
@@ -520,6 +536,7 @@ body.ios {
ol, ol,
ul { ul {
display: inline-block; display: inline-block;
margin-top: 1px;
padding-left: 30px; padding-left: 30px;
} }
} }
@@ -758,7 +775,7 @@ body.ios {
.col__reply { .col__reply {
position: absolute; position: absolute;
right: 10px; right: 0;
top: 30px; top: 30px;
white-space: nowrap; white-space: nowrap;
width: 65px; width: 65px;

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

@@ -17,7 +17,7 @@
.post { .post {
.post__content { .post__content {
padding: 0; padding: 0 10px 0 0;
} }
.post__header { .post__header {

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

@@ -36,113 +36,111 @@
} }
} }
.post {
.attachment { .attachment {
.attachment__content { .attachment__content {
border-radius: 4px; border-radius: 4px;
border-style: solid; border-style: solid;
border-width: 1px; border-width: 1px;
margin: 0 0 5px 0; margin: 0 0 5px 0;
padding: 2px 5px; padding: 2px 5px;
}
.attachment__thumb-pretext {
background: transparent;
border: none;
margin-left: 5px;
}
.attachment__container {
border-left-style: solid;
border-left-width: 4px;
padding: 10px;
&.attachment__container--good {
border-left-color: #00c100;
} }
&.attachment__container--warning { .attachment__thumb-pretext {
border-left-color: #dede01; background: transparent;
border: none;
margin-left: 5px;
} }
&.attachment__container--danger { .attachment__container {
border-left-color: #e40303; border-left-style: solid;
border-left-width: 4px;
padding: 10px;
&.attachment__container--good {
border-left-color: #00c100;
}
&.attachment__container--warning {
border-left-color: #dede01;
}
&.attachment__container--danger {
border-left-color: #e40303;
}
} }
}
.attachment__body { .attachment__body {
float: left; float: left;
overflow-x: auto; overflow-x: auto;
overflow-y: hidden; overflow-y: hidden;
padding-right: 5px; padding-right: 5px;
width: 80%; width: 80%;
&.attachment__body--no_thumb { &.attachment__body--no_thumb {
width: 100%; width: 100%;
}
} }
}
.attachment__text p:last-of-type { .attachment__text p:last-of-type {
display: inline-block; display: inline-block;
}
.attachment__image {
max-height: 300px;
}
.attachment__author-name {
@include opacity(.6);
}
.attachment__title {
font-size: 14px;
font-weight: 600;
height: 22px;
line-height: 18px;
margin: 5px 0;
padding: 0;
}
.attachment-link-more {
display: inline-block;
font-size: .9em;
margin: 5px 0;
}
.attachment__author-icon {
@include border-radius(50px);
height: 14px;
margin-right: 5px;
width: 14px;
}
.attachment__image {
margin-bottom: 1em;
max-width: 100%;
}
.attachment__thumb-container {
float: right;
text-align: right;
width: 80px;
img {
max-height: 75px;
max-width: 100%;
} }
}
.attachment-fields { .attachment__image {
width: 100%; margin-bottom: 1em;
max-height: 300px;
max-width: 500px;
}
.attachment-field__caption { .attachment__author-name {
@include opacity(.6);
}
.attachment__title {
font-size: 14px;
font-weight: 600; font-weight: 600;
padding-top: .7em; height: 22px;
line-height: 18px;
margin: 5px 0;
padding: 0;
} }
.attachment-field { .attachment-link-more {
p { display: inline-block;
margin: 0; font-size: .9em;
margin: 5px 0;
}
.attachment__author-icon {
@include border-radius(50px);
height: 14px;
margin-right: 5px;
width: 14px;
}
.attachment__thumb-container {
float: right;
text-align: right;
width: 80px;
img {
max-height: 75px;
max-width: 100%;
}
}
.attachment-fields {
width: 100%;
.attachment-field__caption {
font-weight: 600;
padding-top: .7em;
}
.attachment-field {
p {
margin: 0;
}
} }
} }
} }

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

@@ -26,6 +26,10 @@
} }
} }
.member-select__container {
margin-top: 10px;
}
.user-popover { .user-popover {
pointer-events: none; pointer-events: none;
} }
@@ -51,11 +55,6 @@
} }
.post { .post {
&.post--compact {
}
.post__dropdown { .post__dropdown {
display: inline-block; display: inline-block;
height: 20px; height: 20px;

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

@@ -85,85 +85,103 @@
.post { .post {
&.post--compact { &.post--compact {
padding: 5px .5em 0 80px; &:not(.post--thread) {
padding: 5px .5em 0 70px;
.post__link { .post__link {
margin: 4px 0 7px; 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;
margin-right: 2px;
padding-right: 10px;
position: relative;
z-index: 1;
&:after {
content: ':';
display: inline-block;
font-family: FontAwesome;
font-size: 19px;
position: absolute;
right: 3px;
text-rendering: auto;
top: -5px;
}
} }
.col__reply { .post__time {
top: 2px; font-size: .85em;
left: -70px;
position: absolute;
text-align: right;
top: 4px;
width: 60px;
} }
}
&.other--root { span {
.post__body { p {
> div { &:last-child {
&:first-child { margin-bottom: .3em;
min-height: 21px;
} }
} }
} }
.post__link + .post__body { .post__header {
float: left;
height: 21px;
padding-top: 3px;
.col__name {
font-weight: bold;
margin-right: 2px;
padding-right: 10px;
position: relative;
z-index: 1;
&:after {
content: ':';
display: inline-block;
font-family: FontAwesome;
font-size: 19px;
position: absolute;
right: 3px;
text-rendering: auto;
top: -5px;
}
}
.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; clear: both;
} }
&.post--comment { .post__body {
.post__header { width: 100%;
.col__reply {
top: 0;
}
}
} }
}
.post-code { .post__content {
clear: both; padding-right: 85px;
}
} }
&.same--root { &.same--root {
&.same--user { &.same--user {
padding-left: 80px; padding-left: 70px;
.post__header {
.col__reply {
top: 4px;
}
}
.post__img { .post__img {
img { img {
@@ -194,14 +212,6 @@
} }
} }
} }
.post__body {
width: 100%;
}
.post__content {
padding-right: 85px;
}
} }
&.same--root { &.same--root {

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

@@ -654,7 +654,7 @@ export function applyTheme(theme) {
changeCss('.app__body .post-list__arrows', 'fill:' + changeOpacity(theme.centerChannelColor, 0.3), 1); changeCss('.app__body .post-list__arrows', 'fill:' + changeOpacity(theme.centerChannelColor, 0.3), 1);
changeCss('.app__body .sidebar--left, .app__body .sidebar--right .sidebar--right__header, .app__body .suggestion-list__content .command', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2), 1); changeCss('.app__body .sidebar--left, .app__body .sidebar--right .sidebar--right__header, .app__body .suggestion-list__content .command', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2), 1);
changeCss('.app__body .app__content, .app__body .post-create__container .post-create-body .btn-file, .app__body .post-create__container .post-create-footer .msg-typing, .app__body .suggestion-list__content .command, .app__body .modal .modal-content, .app__body .dropdown-menu, .app__body .popover, .app__body .mentions__name, .app__body .tip-overlay', 'color:' + theme.centerChannelColor, 1); changeCss('.app__body .app__content, .app__body .post-create__container .post-create-body .btn-file, .app__body .post-create__container .post-create-footer .msg-typing, .app__body .suggestion-list__content .command, .app__body .modal .modal-content, .app__body .dropdown-menu, .app__body .popover, .app__body .mentions__name, .app__body .tip-overlay', 'color:' + theme.centerChannelColor, 1);
changeCss('.app__body .post .post__link', 'color:' + changeOpacity(theme.centerChannelColor, 0.6), 1); changeCss('.app__body .post .post__link', 'color:' + changeOpacity(theme.centerChannelColor, 0.65), 1);
changeCss('.app__body #archive-link-home, .video-div .video-thumbnail__error', 'background:' + changeOpacity(theme.centerChannelColor, 0.15), 1); changeCss('.app__body #archive-link-home, .video-div .video-thumbnail__error', 'background:' + changeOpacity(theme.centerChannelColor, 0.15), 1);
changeCss('.app__body #post-create', 'color:' + theme.centerChannelColor, 2); changeCss('.app__body #post-create', 'color:' + theme.centerChannelColor, 2);
changeCss('.app__body .mentions--top, .app__body .suggestion-list', 'box-shadow:' + changeOpacity(theme.centerChannelColor, 0.2) + ' 1px -3px 12px', 3); changeCss('.app__body .mentions--top, .app__body .suggestion-list', 'box-shadow:' + changeOpacity(theme.centerChannelColor, 0.2) + ' 1px -3px 12px', 3);