summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md6
-rw-r--r--api/user.go5
-rw-r--r--model/user.go5
-rw-r--r--web/react/components/file_attachment.jsx16
-rw-r--r--web/react/components/post_list.jsx10
-rw-r--r--web/react/components/setting_item_min.jsx8
-rw-r--r--web/react/components/sidebar.jsx8
-rw-r--r--web/react/components/team_export_tab.jsx16
-rw-r--r--web/react/components/user_settings_general.jsx26
-rw-r--r--web/sass-files/sass/partials/_files.scss12
-rw-r--r--web/sass-files/sass/partials/_modal.scss2
-rw-r--r--web/sass-files/sass/partials/_post.scss2
-rw-r--r--web/sass-files/sass/partials/_responsive.scss15
-rw-r--r--web/sass-files/sass/partials/_settings.scss17
14 files changed, 98 insertions, 50 deletions
diff --git a/README.md b/README.md
index 9f6b46d5f..de0f4b079 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,8 @@
-# Mattermost is an open source, on-prem Slack-alternative
+# Mattermost
-Mattermost modernizes team communication without locking in your data to a single provider.
+Mattermost is an open source, on-prem Slack-alternative.
-Offer your end users messaging and file sharing across PCs and phones with archiving and instant search--without losing control of your data.
+It modernizes team communication without locking in your data to a single provider. Offer your end users messaging and file sharing across PCs and phones with archiving and instant search--without losing control of your data.
## All team communication in one place, searchable and accessible anywhere
diff --git a/api/user.go b/api/user.go
index d69244fad..727accd1f 100644
--- a/api/user.go
+++ b/api/user.go
@@ -71,10 +71,7 @@ func createUser(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
- if !model.IsUsernameValid(user.Username) {
- c.Err = model.NewAppError("createUser", "That username is invalid", "might be using a resrved username")
- return
- }
+ // the user's username is checked to be valid when they are saved to the database
user.EmailVerified = false
diff --git a/model/user.go b/model/user.go
index 9f90b8204..05fc96953 100644
--- a/model/user.go
+++ b/model/user.go
@@ -335,11 +335,6 @@ func ComparePassword(hash string, password string) bool {
return err == nil
}
-func IsUsernameValid(username string) bool {
-
- return true
-}
-
var validUsernameChars = regexp.MustCompile(`^[a-z0-9\.\-_]+$`)
var restrictedUsernames = []string{
diff --git a/web/react/components/file_attachment.jsx b/web/react/components/file_attachment.jsx
index 78693df98..c9aa06a97 100644
--- a/web/react/components/file_attachment.jsx
+++ b/web/react/components/file_attachment.jsx
@@ -97,6 +97,7 @@ export default class FileAttachment extends React.Component {
var filename = this.props.filename;
var fileInfo = utils.splitFileLocation(filename);
+ var fileUrl = utils.getFileUrl(filename);
var type = utils.getFileType(fileInfo.ext);
var thumbnail;
@@ -150,14 +151,25 @@ export default class FileAttachment extends React.Component {
{thumbnail}
</a>
<div className='post-image__details'>
- <div
+ <a
+ href={fileUrl}
+ download={filenameString}
data-toggle='tooltip'
title={filenameString}
className='post-image__name'
>
{trimmedFilename}
- </div>
+ </a>
<div>
+ <a
+ href={fileUrl}
+ download={filenameString}
+ className='post-image__download'
+ >
+ <span
+ className='fa fa-download'
+ />
+ </a>
<span className='post-image__type'>{fileInfo.ext.toUpperCase()}</span>
<span className='post-image__size'>{fileSizeString}</span>
</div>
diff --git a/web/react/components/post_list.jsx b/web/react/components/post_list.jsx
index d7c0d4862..9d95887d9 100644
--- a/web/react/components/post_list.jsx
+++ b/web/react/components/post_list.jsx
@@ -152,6 +152,10 @@ export default class PostList extends React.Component {
postHolder.off('scroll');
}
componentDidUpdate(prevProps, prevState) {
+ if (!this.props.isActive) {
+ return;
+ }
+
$('.post-list__content div .post').removeClass('post--last');
$('.post-list__content div:last-child .post').addClass('post--last');
@@ -219,8 +223,8 @@ export default class PostList extends React.Component {
scrollToBottom(force) {
this.isUserScroll = false;
var postHolder = $(React.findDOMNode(this.refs.postlist));
- if ($('#new_message')[0] && !this.userHasSeenNew && !force) {
- $('#new_message')[0].scrollIntoView();
+ if ($('#new_message_' + this.props.channelId)[0] && !this.userHasSeenNew && !force) {
+ $('#new_message_' + this.props.channelId)[0].scrollIntoView();
} else {
postHolder.addClass('hide-scroll');
postHolder[0].scrollTop = postHolder[0].scrollHeight;
@@ -539,7 +543,7 @@ export default class PostList extends React.Component {
// Temporary fix to solve ie10/11 rendering issue
let newSeparatorId = '';
if (!utils.isBrowserIE()) {
- newSeparatorId = 'new_message';
+ newSeparatorId = 'new_message_' + this.props.channelId;
}
postCtls.push(
<div
diff --git a/web/react/components/setting_item_min.jsx b/web/react/components/setting_item_min.jsx
index 098729a4f..2c0fdf2f4 100644
--- a/web/react/components/setting_item_min.jsx
+++ b/web/react/components/setting_item_min.jsx
@@ -12,14 +12,18 @@ export default class SettingItemMin extends React.Component {
href='#'
onClick={this.props.updateSection}
>
- Edit
+ <i className='fa fa-pencil'/>
+ {'Edit'}
</a>
</li>
);
}
return (
- <ul className='section-min'>
+ <ul
+ className='section-min'
+ onClick={this.props.updateSection}
+ >
<li className='col-sm-10 section-title'>{this.props.title}</li>
{editButton}
<li className='col-sm-7 section-describe'>{this.props.describe}</li>
diff --git a/web/react/components/sidebar.jsx b/web/react/components/sidebar.jsx
index 983260187..ad934d271 100644
--- a/web/react/components/sidebar.jsx
+++ b/web/react/components/sidebar.jsx
@@ -315,10 +315,12 @@ export default class Sidebar extends React.Component {
if (unread) {
titleClass = 'unread-title';
- if (!this.firstUnreadChannel) {
- this.firstUnreadChannel = channel.name;
+ if (channel.id !== activeId) {
+ if (!this.firstUnreadChannel) {
+ this.firstUnreadChannel = channel.name;
+ }
+ this.lastUnreadChannel = channel.name;
}
- this.lastUnreadChannel = channel.name;
}
var badge = null;
diff --git a/web/react/components/team_export_tab.jsx b/web/react/components/team_export_tab.jsx
index 1bc5abdb1..2914904ad 100644
--- a/web/react/components/team_export_tab.jsx
+++ b/web/react/components/team_export_tab.jsx
@@ -75,15 +75,13 @@ export default class TeamExportTab extends React.Component {
<li className='col-xs-offset-3 col-xs-8'>
<ul className='setting-list'>
<li className='setting-list-item'>
- <span className='btn btn-sm btn-primary btn-file sel-btn'>
- <a
- className='btn btn-sm btn-primary'
- href='#'
- onClick={this.doExport}
- >
- {'Export'}
- </a>
- </span>
+ <a
+ className='btn btn-sm btn-primary btn-file sel-btn'
+ href='#'
+ onClick={this.doExport}
+ >
+ {'Export'}
+ </a>
</li>
</ul>
</li>
diff --git a/web/react/components/user_settings_general.jsx b/web/react/components/user_settings_general.jsx
index f2127ce0c..184534a9a 100644
--- a/web/react/components/user_settings_general.jsx
+++ b/web/react/components/user_settings_general.jsx
@@ -238,7 +238,7 @@ export default class UserSettingsGeneralTab extends React.Component {
key='firstNameSetting'
className='form-group'
>
- <label className='col-sm-5 control-label'>First Name</label>
+ <label className='col-sm-5 control-label'>{'First Name'}</label>
<div className='col-sm-7'>
<input
className='form-control'
@@ -255,7 +255,7 @@ export default class UserSettingsGeneralTab extends React.Component {
key='lastNameSetting'
className='form-group'
>
- <label className='col-sm-5 control-label'>Last Name</label>
+ <label className='col-sm-5 control-label'>{'Last Name'}</label>
<div className='col-sm-7'>
<input
className='form-control'
@@ -278,14 +278,14 @@ export default class UserSettingsGeneralTab extends React.Component {
href='#'
onClick={notifClick.bind(this)}
>
- Notifications
+ {'Notifications'}
</a>
);
const extraInfo = (
<span>
- By default, you will receive mention notifications when someone types your first name.
- Go to {notifLink} settings to change this default.
+ {'By default, you will receive mention notifications when someone types your first name. '}
+ {'Go to '} {notifLink} {'settings to change this default.'}
</span>
);
@@ -351,8 +351,8 @@ export default class UserSettingsGeneralTab extends React.Component {
const extraInfo = (
<span>
- Use Nickname for a name you might be called that is different from your first name and user name.
- This is most often used when two or more people have similar sounding names and usernames.
+ {'Use Nickname for a name you might be called that is different from your first name and user name.'}
+ {'This is most often used when two or more people have similar sounding names and usernames.'}
</span>
);
@@ -406,7 +406,7 @@ export default class UserSettingsGeneralTab extends React.Component {
</div>
);
- const extraInfo = (<span>Pick something easy for teammates to recognize and recall.</span>);
+ const extraInfo = (<span>{'Pick something easy for teammates to recognize and recall.'}</span>);
usernameSection = (
<SettingItemMax
@@ -438,13 +438,13 @@ export default class UserSettingsGeneralTab extends React.Component {
let helpText = <div>Email is used for notifications, and requires verification if changed.</div>;
if (!this.state.emailEnabled) {
- helpText = <div className='text-danger'><br />Email has been disabled by your system administrator. No notification emails will be sent until it is enabled.</div>;
+ helpText = <div className='setting-list__hint text-danger'>{'Email has been disabled by your system administrator. No notification emails will be sent until it is enabled.'}</div>;
}
inputs.push(
<div key='emailSetting'>
<div className='form-group'>
- <label className='col-sm-5 control-label'>Primary Email</label>
+ <label className='col-sm-5 control-label'>{'Primary Email'}</label>
<div className='col-sm-7'>
<input
className='form-control'
@@ -526,18 +526,18 @@ export default class UserSettingsGeneralTab extends React.Component {
data-dismiss='modal'
aria-label='Close'
>
- <span aria-hidden='true'>&times;</span>
+ <span aria-hidden='true'>{'×'}</span>
</button>
<h4
className='modal-title'
ref='title'
>
<i className='modal-back'></i>
- General Settings
+ {'General Settings'}
</h4>
</div>
<div className='user-settings'>
- <h3 className='tab-header'>General Settings</h3>
+ <h3 className='tab-header'>{'General Settings'}</h3>
<div className='divider-dark first'/>
{nameSection}
<div className='divider-light'/>
diff --git a/web/sass-files/sass/partials/_files.scss b/web/sass-files/sass/partials/_files.scss
index 70f440989..405265f92 100644
--- a/web/sass-files/sass/partials/_files.scss
+++ b/web/sass-files/sass/partials/_files.scss
@@ -61,8 +61,8 @@
cursor: pointer;
z-index: 5;
opacity: inherit;
- text-shadow: 0 0px 3px #444;
- text-shadow: 0 0px 3px rgba(0, 0, 0, 0.7);
+ text-shadow: 0 0px 3px #444;
+ text-shadow: 0 0px 3px rgba(0, 0, 0, 0.7);
}
}
}
@@ -159,6 +159,14 @@
padding: 7px;
.post-image__name {
margin-bottom: 3px;
+ display: block;
+ color: #333;
+ }
+ .post-image__download {
+ display: inline-block;
+ padding-right: 7px;
+ cursor: pointer;
+ color: #555;
}
.post-image__type {
color: grey;
diff --git a/web/sass-files/sass/partials/_modal.scss b/web/sass-files/sass/partials/_modal.scss
index 29e05f6bf..b94ed2113 100644
--- a/web/sass-files/sass/partials/_modal.scss
+++ b/web/sass-files/sass/partials/_modal.scss
@@ -82,7 +82,7 @@
.btn {
&.btn-primary {
float: right;
- margin-top: -4px;
+ margin: -4px 25px 0 0;
position: relative;
i {
margin-right: 5px;
diff --git a/web/sass-files/sass/partials/_post.scss b/web/sass-files/sass/partials/_post.scss
index 5ae9e656d..6940cf2fb 100644
--- a/web/sass-files/sass/partials/_post.scss
+++ b/web/sass-files/sass/partials/_post.scss
@@ -200,7 +200,7 @@ body.ios {
height: 37px;
font-size: 18px;
line-height: 37px;
- vertical-align: top;
+ vertical-align: bottom;
text-align: center;
@include single-transition(all, 0.15s);
&:active {
diff --git a/web/sass-files/sass/partials/_responsive.scss b/web/sass-files/sass/partials/_responsive.scss
index 24c79e6c2..32d65b86b 100644
--- a/web/sass-files/sass/partials/_responsive.scss
+++ b/web/sass-files/sass/partials/_responsive.scss
@@ -413,6 +413,9 @@
}
}
.post-create__container {
+ .post-right__container & {
+ padding: 0 1em;
+ }
form {
padding: 0;
}
@@ -423,7 +426,17 @@
table-layout: fixed;
.post-body__cell {
display: table-cell;
- padding-left: 1em;
+ padding-left: 45px;
+ }
+ .app__content & {
+ .btn-file {
+ width: 45px;
+ padding: 0;
+ line-height: 36px;
+ bottom: -2px;
+ left: 0;
+ top: auto;
+ }
}
.send-button {
display: table-cell;
diff --git a/web/sass-files/sass/partials/_settings.scss b/web/sass-files/sass/partials/_settings.scss
index 25c093957..2b59a943b 100644
--- a/web/sass-files/sass/partials/_settings.scss
+++ b/web/sass-files/sass/partials/_settings.scss
@@ -56,7 +56,17 @@
.section-min {
padding: 1em 0;
margin-bottom: 0;
+ cursor: pointer;
@include clearfix;
+ &:hover {
+ background: #f9f9f9;
+ }
+ &:hover .fa {
+ display: inline-block;
+ }
+ &:hover .section-edit {
+ text-decoration: underline;
+ }
}
.section-max {
@@ -77,6 +87,12 @@
.section-edit {
text-align: right;
margin-bottom: 5px;
+ .fa {
+ margin-right: 7px;
+ font-size: 12px;
+ color: #aaa;
+ display: none;
+ }
}
.section-describe {
@@ -97,7 +113,6 @@
}
.setting-list__hint {
- color: #555;
margin-top: 20px;
}