summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/user.go7
-rw-r--r--store/sql_user_store.go21
-rw-r--r--store/sql_user_store_test.go2
-rw-r--r--store/store.go2
-rw-r--r--web/react/components/channel_loader.jsx10
-rw-r--r--web/react/components/create_comment.jsx5
-rw-r--r--web/react/components/file_upload.jsx6
-rw-r--r--web/react/components/search_results_item.jsx118
-rw-r--r--web/react/components/user_settings/user_settings_display.jsx2
-rw-r--r--web/sass-files/sass/partials/_headers.scss1
-rw-r--r--web/sass-files/sass/partials/_post.scss3
-rw-r--r--web/sass-files/sass/partials/_search.scss24
-rw-r--r--web/static/i18n/es.json4
13 files changed, 125 insertions, 80 deletions
diff --git a/api/user.go b/api/user.go
index a6817caa2..9926f3ff3 100644
--- a/api/user.go
+++ b/api/user.go
@@ -2091,13 +2091,16 @@ func switchToSSO(c *Context, w http.ResponseWriter, r *http.Request) {
func CompleteSwitchWithOAuth(c *Context, w http.ResponseWriter, r *http.Request, service string, userData io.ReadCloser, team *model.Team, email string) {
authData := ""
+ ssoEmail := ""
provider := einterfaces.GetOauthProvider(service)
if provider == nil {
c.Err = model.NewLocAppError("CompleteClaimWithOAuth", "api.user.complete_switch_with_oauth.unavailable.app_error",
map[string]interface{}{"Service": service}, "")
return
} else {
- authData = provider.GetAuthDataFromJson(userData)
+ ssoUser := provider.GetUserFromJson(userData)
+ authData = ssoUser.AuthData
+ ssoEmail = ssoUser.Email
}
if len(authData) == 0 {
@@ -2124,7 +2127,7 @@ func CompleteSwitchWithOAuth(c *Context, w http.ResponseWriter, r *http.Request,
return
}
- if result := <-Srv.Store.User().UpdateAuthData(user.Id, service, authData); result.Err != nil {
+ if result := <-Srv.Store.User().UpdateAuthData(user.Id, service, authData, ssoEmail); result.Err != nil {
c.Err = result.Err
return
}
diff --git a/store/sql_user_store.go b/store/sql_user_store.go
index 0b6970c96..b1544289d 100644
--- a/store/sql_user_store.go
+++ b/store/sql_user_store.go
@@ -305,7 +305,7 @@ func (us SqlUserStore) UpdateFailedPasswordAttempts(userId string, attempts int)
return storeChannel
}
-func (us SqlUserStore) UpdateAuthData(userId, service, authData string) StoreChannel {
+func (us SqlUserStore) UpdateAuthData(userId, service, authData, email string) StoreChannel {
storeChannel := make(StoreChannel)
@@ -314,7 +314,24 @@ func (us SqlUserStore) UpdateAuthData(userId, service, authData string) StoreCha
updateAt := model.GetMillis()
- if _, err := us.GetMaster().Exec("UPDATE Users SET Password = '', LastPasswordUpdate = :LastPasswordUpdate, UpdateAt = :UpdateAt, FailedAttempts = 0, AuthService = :AuthService, AuthData = :AuthData WHERE Id = :UserId", map[string]interface{}{"LastPasswordUpdate": updateAt, "UpdateAt": updateAt, "UserId": userId, "AuthService": service, "AuthData": authData}); err != nil {
+ query := `
+ UPDATE
+ Users
+ SET
+ Password = '',
+ LastPasswordUpdate = :LastPasswordUpdate,
+ UpdateAt = :UpdateAt,
+ FailedAttempts = 0,
+ AuthService = :AuthService,
+ AuthData = :AuthData`
+
+ if len(email) != 0 {
+ query += ", Email = :Email"
+ }
+
+ query += " WHERE Id = :UserId"
+
+ if _, err := us.GetMaster().Exec(query, map[string]interface{}{"LastPasswordUpdate": updateAt, "UpdateAt": updateAt, "UserId": userId, "AuthService": service, "AuthData": authData, "Email": email}); err != nil {
result.Err = model.NewLocAppError("SqlUserStore.UpdateAuthData", "store.sql_user.update_auth_data.app_error", nil, "id="+userId+", "+err.Error())
} else {
result.Data = userId
diff --git a/store/sql_user_store_test.go b/store/sql_user_store_test.go
index d1ee5e647..2350bad30 100644
--- a/store/sql_user_store_test.go
+++ b/store/sql_user_store_test.go
@@ -402,7 +402,7 @@ func TestUserStoreUpdateAuthData(t *testing.T) {
service := "someservice"
authData := "1"
- if err := (<-store.User().UpdateAuthData(u1.Id, service, authData)).Err; err != nil {
+ if err := (<-store.User().UpdateAuthData(u1.Id, service, authData, "")).Err; err != nil {
t.Fatal(err)
}
diff --git a/store/store.go b/store/store.go
index 95df368ed..b6b86e0d9 100644
--- a/store/store.go
+++ b/store/store.go
@@ -112,7 +112,7 @@ type UserStore interface {
UpdateLastActivityAt(userId string, time int64) StoreChannel
UpdateUserAndSessionActivity(userId string, sessionId string, time int64) StoreChannel
UpdatePassword(userId, newPassword string) StoreChannel
- UpdateAuthData(userId, service, authData string) StoreChannel
+ UpdateAuthData(userId, service, authData, email string) StoreChannel
Get(id string) StoreChannel
GetProfiles(teamId string) StoreChannel
GetByEmail(teamId string, email string) StoreChannel
diff --git a/web/react/components/channel_loader.jsx b/web/react/components/channel_loader.jsx
index 15571ad93..174c8c4e1 100644
--- a/web/react/components/channel_loader.jsx
+++ b/web/react/components/channel_loader.jsx
@@ -128,6 +128,16 @@ class ChannelLoader extends React.Component {
}
});
+ $('body').on('mouseenter mouseleave', '.search-item__container .post', function mouseOver(ev) {
+ if (ev.type === 'mouseenter') {
+ $(this).closest('.search-item__container').find('.date-separator').addClass('hovered--after');
+ $(this).closest('.search-item__container').next('div').find('.date-separator').addClass('hovered--before');
+ } else {
+ $(this).closest('.search-item__container').find('.date-separator').removeClass('hovered--after');
+ $(this).closest('.search-item__container').next('div').find('.date-separator').removeClass('hovered--before');
+ }
+ });
+
$('body').on('mouseenter mouseleave', '.post.post--comment.same--root', function mouseOver(ev) {
if (ev.type === 'mouseenter') {
$(this).parent('div').prev('.date-separator, .new-separator').addClass('hovered--comment');
diff --git a/web/react/components/create_comment.jsx b/web/react/components/create_comment.jsx
index 1b552838a..8c49315e7 100644
--- a/web/react/components/create_comment.jsx
+++ b/web/react/components/create_comment.jsx
@@ -202,8 +202,7 @@ class CreateComment extends React.Component {
if (e.keyCode === KeyCodes.UP && this.state.messageText === '') {
e.preventDefault();
- const channelId = ChannelStore.getCurrentId();
- const lastPost = PostStore.getCurrentUsersLatestPost(channelId, this.props.rootId);
+ const lastPost = PostStore.getCurrentUsersLatestPost(this.props.channelId, this.props.rootId);
if (!lastPost) {
return;
}
@@ -402,4 +401,4 @@ CreateComment.propTypes = {
rootId: React.PropTypes.string.isRequired
};
-export default injectIntl(CreateComment); \ No newline at end of file
+export default injectIntl(CreateComment);
diff --git a/web/react/components/file_upload.jsx b/web/react/components/file_upload.jsx
index 626dbc5b3..746289653 100644
--- a/web/react/components/file_upload.jsx
+++ b/web/react/components/file_upload.jsx
@@ -101,9 +101,9 @@ class FileUpload extends React.Component {
} else if (tooLargeFiles.length > 1) {
var tooLargeFilenames = tooLargeFiles.map((file) => file.name).join(', ');
- this.props.onUploadError(formatMessage(holders.filesAbove, {max: (Constants.MAX_FILE_SIZE / 1000000), files: tooLargeFilenames}));
+ this.props.onUploadError(formatMessage(holders.filesAbove, {max: (Constants.MAX_FILE_SIZE / 1000000), filenames: tooLargeFilenames}));
} else if (tooLargeFiles.length > 0) {
- this.props.onUploadError(formatMessage(holders.fileAbove, {max: (Constants.MAX_FILE_SIZE / 1000000), file: tooLargeFiles[0].name}));
+ this.props.onUploadError(formatMessage(holders.fileAbove, {max: (Constants.MAX_FILE_SIZE / 1000000), filename: tooLargeFiles[0].name}));
}
}
@@ -329,4 +329,4 @@ FileUpload.propTypes = {
postType: React.PropTypes.string
};
-export default injectIntl(FileUpload); \ No newline at end of file
+export default injectIntl(FileUpload);
diff --git a/web/react/components/search_results_item.jsx b/web/react/components/search_results_item.jsx
index 0ad091d5b..544ba920a 100644
--- a/web/react/components/search_results_item.jsx
+++ b/web/react/components/search_results_item.jsx
@@ -59,64 +59,74 @@ export default class SearchResultsItem extends React.Component {
};
return (
- <div
- className='search-item-container post'
- >
- <div className='search-channel__name'>{channelName}</div>
- <div className='post__content'>
- <div className='post__img'>
- <img
- src={'/api/v1/users/' + this.props.post.user_id + '/image?time=' + timestamp + '&' + utils.getSessionIndex()}
- height='36'
- width='36'
+ <div className='search-item__container'>
+ <div className='date-separator'>
+ <hr className='separator__hr' />
+ <div className='separator__text'>
+ <FormattedDate
+ value={this.props.post.create_at}
+ day='numeric'
+ month='long'
+ year='numeric'
/>
</div>
- <div>
- <ul className='post__header'>
- <li className='col__name'><strong><UserProfile userId={this.props.post.user_id} /></strong></li>
- <li className='col'>
- <time className='search-item-time'>
- <FormattedDate
- value={this.props.post.create_at}
- day='numeric'
- month='long'
- year='numeric'
- hour12={true}
- hour='2-digit'
- minute='2-digit'
- />
- </time>
- </li>
- <li>
- <a
- href='#'
- className='search-item__jump'
- onClick={this.handleClick}
- >
- <FormattedMessage
- id='search_item.jump'
- defaultMessage='Jump'
- />
- </a>
- </li>
- <li>
- <a
- href='#'
- className='comment-icon__container search-item__comment'
- onClick={this.handleFocusRHSClick}
- >
- <span
- className='comment-icon'
- dangerouslySetInnerHTML={{__html: Constants.REPLY_ICON}}
- />
- </a>
- </li>
- </ul>
- <div className='search-item-snippet'>
- <span
- dangerouslySetInnerHTML={{__html: TextFormatting.formatText(this.props.post.message, formattingOptions)}}
+ </div>
+ <div
+ className='post'
+ >
+ <div className='search-channel__name'>{channelName}</div>
+ <div className='post__content'>
+ <div className='post__img'>
+ <img
+ src={'/api/v1/users/' + this.props.post.user_id + '/image?time=' + timestamp + '&' + utils.getSessionIndex()}
+ height='36'
+ width='36'
/>
</div>
+ <div>
+ <ul className='post__header'>
+ <li className='col__name'><strong><UserProfile userId={this.props.post.user_id} /></strong></li>
+ <li className='col'>
+ <time className='search-item-time'>
+ <FormattedDate
+ value={this.props.post.create_at}
+ hour12={true}
+ hour='2-digit'
+ minute='2-digit'
+ />
+ </time>
+ </li>
+ <li>
+ <a
+ href='#'
+ className='search-item__jump'
+ onClick={this.handleClick}
+ >
+ <FormattedMessage
+ id='search_item.jump'
+ defaultMessage='Jump'
+ />
+ </a>
+ </li>
+ <li>
+ <a
+ href='#'
+ className='comment-icon__container search-item__comment'
+ onClick={this.handleFocusRHSClick}
+ >
+ <span
+ className='comment-icon'
+ dangerouslySetInnerHTML={{__html: Constants.REPLY_ICON}}
+ />
+ </a>
+ </li>
+ </ul>
+ <div className='search-item-snippet'>
+ <span
+ dangerouslySetInnerHTML={{__html: TextFormatting.formatText(this.props.post.message, formattingOptions)}}
+ />
+ </div>
+ </div>
</div>
</div>
</div>
diff --git a/web/react/components/user_settings/user_settings_display.jsx b/web/react/components/user_settings/user_settings_display.jsx
index 3b2a2065b..776bde442 100644
--- a/web/react/components/user_settings/user_settings_display.jsx
+++ b/web/react/components/user_settings/user_settings_display.jsx
@@ -297,7 +297,7 @@ class UserSettingsDisplay extends React.Component {
if (this.state.nameFormat === 'username') {
describe = formatMessage(holders.showUsername);
} else if (this.state.nameFormat === 'full_name') {
- describe = formatMessage(holders.showFullName);
+ describe = formatMessage(holders.showFullname);
} else {
describe = formatMessage(holders.showNickname);
}
diff --git a/web/sass-files/sass/partials/_headers.scss b/web/sass-files/sass/partials/_headers.scss
index e73680b38..4a4de5c3b 100644
--- a/web/sass-files/sass/partials/_headers.scss
+++ b/web/sass-files/sass/partials/_headers.scss
@@ -173,6 +173,7 @@
.team__name {
line-height: 22px;
margin-top: -2px;
+ float: left;
}
.user__name {
@include single-transition(all, 0.1s, linear);
diff --git a/web/sass-files/sass/partials/_post.scss b/web/sass-files/sass/partials/_post.scss
index 73c7bd9cb..2ff49c9b7 100644
--- a/web/sass-files/sass/partials/_post.scss
+++ b/web/sass-files/sass/partials/_post.scss
@@ -764,12 +764,13 @@ body.ios {
}
svg {
+ height: 17px;
width: 17px;
}
.comment-icon {
display: inline-block;
- top: 3px;
+ top: 2px;
position: relative;
margin-right: 3px;
fill: inherit;
diff --git a/web/sass-files/sass/partials/_search.scss b/web/sass-files/sass/partials/_search.scss
index cb125bff0..693c59a31 100644
--- a/web/sass-files/sass/partials/_search.scss
+++ b/web/sass-files/sass/partials/_search.scss
@@ -90,6 +90,7 @@
-webkit-overflow-scrolling: touch;
@include flex(1 1 auto);
height: calc(100% - 56px);
+ padding-top: 10px;
}
.search-results-header {
@@ -104,19 +105,22 @@
border-bottom: $border-gray;
}
-.search-item-container {
- border-top: $border-gray;
- padding: 10px 1em;
- margin: 0;
+.search-item__container {
- &:first-child {
- border: none;
- }
+ .post {
+ padding: 0 1em 1em;
+ margin: 0;
- .search-channel__name {
- font-weight: 600;
- margin: 0 0 10px 0;
+ &:first-child {
+ border: none;
+ }
+
+ .search-channel__name {
+ font-weight: 600;
+ margin: 0 0 10px 0;
+ }
}
+
}
.search-item__jump {
diff --git a/web/static/i18n/es.json b/web/static/i18n/es.json
index ceeb911a9..0a780c442 100644
--- a/web/static/i18n/es.json
+++ b/web/static/i18n/es.json
@@ -567,8 +567,8 @@
"claim.email_to_sso.pwd": "Contraseña",
"claim.email_to_sso.pwdError": "Por favor introduce tu contraseña.",
"claim.email_to_sso.ssoType": "Al reclamar tu cuenta, sólo podrás iniciar sesión con {type} SSO",
- "claim.email_to_sso.switchTo": "Cambiar cuenta a ",
- "claim.email_to_sso.title": "Cambiar Cuenta de Correo/Contraseña a ",
+ "claim.email_to_sso.switchTo": "Cambiar cuenta a {uiType}",
+ "claim.email_to_sso.title": "Cambiar Cuenta de Correo/Contraseña a {uiType}",
"claim.sso_to_email.confirm": "Confirmar Contraseña",
"claim.sso_to_email.description": "Al cambiar el tipo de cuenta, sólo podrás iniciar sesión con tu correo electrónico y contraseña.",
"claim.sso_to_email.enterPwd": "Por favor ingresa una contraseña.",