diff options
-rw-r--r-- | CHANGELOG.md | 28 | ||||
-rw-r--r-- | api/preference_test.go | 10 | ||||
-rw-r--r-- | api/user.go | 5 | ||||
-rw-r--r-- | model/preference.go | 1 | ||||
-rw-r--r-- | web/react/components/posts_view_container.jsx | 2 | ||||
-rw-r--r-- | web/react/components/rhs_root_post.jsx | 4 | ||||
-rw-r--r-- | web/react/components/search_autocomplete.jsx | 15 | ||||
-rw-r--r-- | web/react/utils/markdown.jsx | 4 | ||||
-rw-r--r-- | web/react/utils/text_formatting.jsx | 8 | ||||
-rw-r--r-- | web/react/utils/utils.jsx | 5 | ||||
-rw-r--r-- | web/sass-files/sass/partials/_markdown.scss | 11 | ||||
-rw-r--r-- | web/sass-files/sass/partials/_popover.scss | 28 | ||||
-rw-r--r-- | web/sass-files/sass/partials/_post.scss | 2 |
13 files changed, 94 insertions, 29 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ac8a3261..142e15d91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,8 @@ Messaging and Notifications - Users can now search for teammates to add to **Direct Message** list via **More** menu - Users can now personalize Direct Messages list by removing users listed -- Link previews - Adding URL with .gif file adds image below message +- Link previews - Adding URL with .gif file adds image below message +- Added new browser tab alerts to indicate unread messages and mentions Search @@ -38,6 +39,8 @@ User Interface - Languages include `Diff, Apache, Makefile, HTTP, JSON, Markdown, Java, CSS, nginx, ObjectiveC, Python, XML, Perl, Bash, PHP, Coffee, C, SQL, Go, Ruby, Java, and ini`. - Use by adding the name of the language on the first link of the code block, for example: ```python - Syntax color theme can be defined under **Account Settings** > **Appearance Settings** > **Custom Theme** +- Updated Drag & Drop UI +- Added 24 hour time display option Team Settings @@ -49,6 +52,7 @@ Extras - Added `/shrug KEYWORD` command to output: `¯\_(ツ)_/¯ KEYWORD` - Added `/me KEYWORD` command to output: _`KEYWORD`_ +- Added setting option to send a message on control-enter instead of enter System Console @@ -57,7 +61,10 @@ System Console #### Bug Fixes -- Various fixes to theme colors +- Various fixes to theme colors +- Fixed issue with the centre channel scroll position jumping when right hand side was opened and closed +- Added support for simultaneous login to different teams in different browser tabs +- Incoming webhooks no longer disrupted when channel is deleted ### Compatibility @@ -93,7 +100,17 @@ The following is for informational purposes only, no action needed. Mattermost a #### Known Issues - Microsoft Edge does not yet support drag and drop -- Incoming webhooks no longer disrupted when channel is deleted +- After upgrading to v1.2 existing users will see the newly added tutorial tips upon login (this is a special case for v1.2 and will not happen in future upgrades) +- Channel list becomes reordered when there are lowercase channel names in a Postgres database +- Member list only shows "20" members for channels with more than 20 members +- Searches containing punctuation are not highlighted in the results (including in: or from: search modifiers and searches with quotations) +- Media files of type .avi .mkv .wmv .mov .flv .mp4a do not play properly +- Editing a post so that it's text is blank (which should delete it) throws a 404 +- No scroll bar in centre channel +- Theme color import from Slack fails to import the “Active Channel” selection color +- Pasting images into text box fails to upload on [BROWSERS] +- Users cannot claim accounts imported from Slack via password reset +- Slack import @mentions break #### Contributors @@ -110,7 +127,10 @@ Many thanks to our external contributors. In no particular order: - [jvasallo](https://github.com/jvasallo) - [layzerar](https://github.com/layzerar) - [optimistiks](https://github.com/optimistiks) -- [layzerar](https://github.com/layzerar) +- [Tsynapse](https://github.com/Tsynapse) +- [vinnymac](https://github.com/vinnymac) +- [yuvipanda](https://github.com/yuvipanda) +- [toyorg](https://github.com/toyorg) ## Release v1.1.1 (Bug Fix Release) diff --git a/api/preference_test.go b/api/preference_test.go index eaa92fe47..2f6204246 100644 --- a/api/preference_test.go +++ b/api/preference_test.go @@ -48,14 +48,8 @@ func TestGetAllPreferences(t *testing.T) { if result, err := Client.GetAllPreferences(); err != nil { t.Fatal(err) - } else if data := result.Data.(model.Preferences); len(data) != 3 { + } else if data := result.Data.(model.Preferences); len(data) != 4 { t.Fatal("received the wrong number of preferences") - } else if !((data[0] == preferences1[0] && data[1] == preferences1[1]) || (data[0] == preferences1[1] && data[1] == preferences1[0])) { - for i := 0; i < 3; i++ { - if data[0] != preferences1[i] && data[1] != preferences1[i] && data[2] != preferences1[i] { - t.Fatal("got incorrect preferences") - } - } } Client.LoginByEmail(team.Name, user2.Email, "pwd") @@ -63,7 +57,7 @@ func TestGetAllPreferences(t *testing.T) { // note that user2 will automatically have a preference set for them to show user1 for direct messages if result, err := Client.GetAllPreferences(); err != nil { t.Fatal(err) - } else if data := result.Data.(model.Preferences); len(data) != 1 { + } else if data := result.Data.(model.Preferences); len(data) != 2 { t.Fatal("received the wrong number of preferences") } } diff --git a/api/user.go b/api/user.go index 774ceddbf..4a52cf88b 100644 --- a/api/user.go +++ b/api/user.go @@ -213,6 +213,11 @@ func CreateUser(c *Context, team *model.Team, user *model.User) *model.User { } } + pref := model.Preference{UserId: ruser.Id, Category: model.PREFERENCE_CATEGORY_TUTORIAL_STEPS, Name: ruser.Id, Value: "0"} + if presult := <-Srv.Store.Preference().Save(&model.Preferences{pref}); presult.Err != nil { + l4g.Error("Encountered error saving tutorial preference, err=%v", presult.Err.Message) + } + ruser.Sanitize(map[string]bool{}) // This message goes to every channel, so the channelId is irrelevant diff --git a/model/preference.go b/model/preference.go index bcd0237f1..892ae82aa 100644 --- a/model/preference.go +++ b/model/preference.go @@ -11,6 +11,7 @@ import ( const ( PREFERENCE_CATEGORY_DIRECT_CHANNEL_SHOW = "direct_channel_show" + PREFERENCE_CATEGORY_TUTORIAL_STEPS = "tutorial_step" ) type Preference struct { diff --git a/web/react/components/posts_view_container.jsx b/web/react/components/posts_view_container.jsx index 761664602..5059747bd 100644 --- a/web/react/components/posts_view_container.jsx +++ b/web/react/components/posts_view_container.jsx @@ -87,6 +87,8 @@ export default class PostsViewContainer extends React.Component { // Has the channel really changed? if (channelId === channels[this.state.currentChannelIndex]) { + // Dirty hack + this.forceUpdate(); return; } diff --git a/web/react/components/rhs_root_post.jsx b/web/react/components/rhs_root_post.jsx index 21e52b438..e3b023841 100644 --- a/web/react/components/rhs_root_post.jsx +++ b/web/react/components/rhs_root_post.jsx @@ -9,6 +9,7 @@ var utils = require('../utils/utils.jsx'); var FileAttachmentList = require('./file_attachment_list.jsx'); var twemoji = require('twemoji'); var Constants = require('../utils/constants.jsx'); +const PostBodyAdditionalContent = require('./post_body_additional_content.jsx'); export default class RhsRootPost extends React.Component { constructor(props) { @@ -180,6 +181,9 @@ export default class RhsRootPost extends React.Component { onClick={TextFormatting.handleClick} dangerouslySetInnerHTML={{__html: TextFormatting.formatText(post.message)}} /> + <PostBodyAdditionalContent + post={post} + /> {fileAttachment} </div> </div> diff --git a/web/react/components/search_autocomplete.jsx b/web/react/components/search_autocomplete.jsx index 736919697..d245c6bac 100644 --- a/web/react/components/search_autocomplete.jsx +++ b/web/react/components/search_autocomplete.jsx @@ -189,7 +189,16 @@ export default class SearchAutocomplete extends React.Component { channels = channels.filter((channel) => channel.type !== 'D'); } - channels.sort((a, b) => a.name.localeCompare(b.name)); + channels.sort((a, b) => { + // put public channels first and then sort alphabebetically + if (a.type === b.type) { + return a.name.localeCompare(b.name); + } else if (a.type === Constants.OPEN_CHANNEL) { + return -1; + } + + return 1; + }); suggestions = channels; } else if (mode === 'users') { @@ -289,7 +298,7 @@ export default class SearchAutocomplete extends React.Component { key='public-channel-divider' className='search-autocomplete__divider' > - {'Public ' + Utils.getChannelTerm(Constants.OPEN_CHANNEL) + 's'} + <span>{'Public ' + Utils.getChannelTerm(Constants.OPEN_CHANNEL) + 's'}</span> </div> ); suggestions = suggestions.concat(publicChannels.map(this.renderChannelSuggestion)); @@ -302,7 +311,7 @@ export default class SearchAutocomplete extends React.Component { key='private-channel-divider' className='search-autocomplete__divider' > - {'Private ' + Utils.getChannelTerm(Constants.PRIVATE_CHANNEL) + 's'} + <span>{'Private ' + Utils.getChannelTerm(Constants.PRIVATE_CHANNEL) + 's'}</span> </div> ); suggestions = suggestions.concat(privateChannels.map(this.renderChannelSuggestion)); diff --git a/web/react/utils/markdown.jsx b/web/react/utils/markdown.jsx index 374caf6dc..946f93078 100644 --- a/web/react/utils/markdown.jsx +++ b/web/react/utils/markdown.jsx @@ -24,7 +24,7 @@ class MattermostInlineLexer extends marked.InlineLexer { // modified version of the regex that doesn't break up words in snake_case, // allows for links starting with www, and allows links succounded by parentheses // the original is /^[\s\S]+?(?=[\\<!\[_*`~]|https?:\/\/| {2,}\n|$)/ - this.rules.text = /^[\s\S]+?(?=[^\w\/]_|[\\<!\[*`~]|https?:\/\/|www\.|\(| {2,}\n|$)/; + this.rules.text = /^[\s\S]+?(?:[^\w\/](?=_)|(?=_\W|[\\<!\[*`~]|https?:\/\/|www\.|\(| {2,}\n|$))/; // modified version of the regex that allows links starting with www and those surrounded // by parentheses @@ -94,7 +94,7 @@ class MattermostMarkdownRenderer extends marked.Renderer { if (title) { out += ' title="' + title + '"'; } - out += ' onload="window.markdownImageLoaded(this)" class="markdown-inline-img"'; + out += ' onload="window.markdownImageLoaded(this)" onerror="window.markdownImageLoaded(this)" class="markdown-inline-img"'; out += this.options.xhtml ? '/>' : '>'; return out; } diff --git a/web/react/utils/text_formatting.jsx b/web/react/utils/text_formatting.jsx index ac26107cc..705d85cf6 100644 --- a/web/react/utils/text_formatting.jsx +++ b/web/react/utils/text_formatting.jsx @@ -135,13 +135,13 @@ function autolinkAtMentions(text, tokens) { return alias; } - function replaceAtMentionWithToken(fullMatch, prefix, mention, username) { + function replaceAtMentionWithToken(fullMatch, mention, username) { let usernameLower = username.toLowerCase(); if (mentionExists(usernameLower)) { // Exact match const alias = addToken(usernameLower, mention, ''); - return prefix + alias; + return alias; } // Not an exact match, attempt to truncate any punctuation to see if we can find a user @@ -154,7 +154,7 @@ function autolinkAtMentions(text, tokens) { if (mentionExists(usernameLower)) { const extraText = originalUsername.substr(c - 1); const alias = addToken(usernameLower, '@' + usernameLower, extraText); - return prefix + alias; + return alias; } } else { // If the last character is not punctuation, no point in going any further @@ -166,7 +166,7 @@ function autolinkAtMentions(text, tokens) { } let output = text; - output = output.replace(/(^|[^a-z0-9])(@([a-z0-9.\-_]*))/gi, replaceAtMentionWithToken); + output = output.replace(/(@([a-z0-9.\-_]*))/gi, replaceAtMentionWithToken); return output; } diff --git a/web/react/utils/utils.jsx b/web/react/utils/utils.jsx index 8052c000c..38f91b35f 100644 --- a/web/react/utils/utils.jsx +++ b/web/react/utils/utils.jsx @@ -513,7 +513,7 @@ export function applyTheme(theme) { changeCss('#post-list .post-list-holder-by-time', 'background:' + theme.centerChannelBg, 1); changeCss('#post-create', 'background:' + theme.centerChannelBg, 1); changeCss('.date-separator .separator__text, .new-separator .separator__text', 'background:' + theme.centerChannelBg, 1); - changeCss('.post-image__column .post-image__details', 'background:' + theme.centerChannelBg, 1); + changeCss('.post-image__column .post-image__details, .search-help-popover .search-autocomplete__divider span', 'background:' + theme.centerChannelBg, 1); changeCss('.sidebar--right, .dropdown-menu, .popover, .tip-overlay', 'background:' + theme.centerChannelBg, 1); changeCss('.popover.bottom>.arrow:after', 'border-bottom-color:' + theme.centerChannelBg, 1); changeCss('.popover.right>.arrow:after, .tip-overlay.tip-overlay--sidebar .arrow, .tip-overlay.tip-overlay--header .arrow', 'border-right-color:' + theme.centerChannelBg, 1); @@ -541,11 +541,12 @@ export function applyTheme(theme) { changeCss('.channel-header #member_popover', 'color:' + changeOpacity(theme.centerChannelColor, 0.8), 1); changeCss('.custom-textarea, .custom-textarea:focus, .preview-container .preview-div, .post-image__column .post-image__details, .sidebar--right .sidebar-right__body, .markdown__table th, .markdown__table td, .command-box, .modal .modal-content, .settings-modal .settings-table .settings-content .divider-light, .webhooks__container, .dropdown-menu, .modal .modal-header, .popover, .mentions--top .mentions-box', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2), 1); changeCss('.popover.bottom>.arrow', 'border-bottom-color:' + changeOpacity(theme.centerChannelColor, 0.25), 1); + changeCss('.search-help-popover .search-autocomplete__divider span', 'color:' + changeOpacity(theme.centerChannelColor, 0.7), 1); changeCss('.popover.right>.arrow', 'border-right-color:' + changeOpacity(theme.centerChannelColor, 0.25), 1); changeCss('.popover.left>.arrow', 'border-left-color:' + changeOpacity(theme.centerChannelColor, 0.25), 1); changeCss('.popover.top>.arrow', 'border-top-color:' + changeOpacity(theme.centerChannelColor, 0.25), 1); changeCss('.command-name, .popover .popover-title', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2), 1); - changeCss('.dropdown-menu .divider', 'background:' + theme.centerChannelColor, 1); + changeCss('.dropdown-menu .divider, .search-help-popover .search-autocomplete__divider:before', 'background:' + theme.centerChannelColor, 1); changeCss('.custom-textarea', 'color:' + theme.centerChannelColor, 1); changeCss('.post-image__column', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2), 2); changeCss('.post-image__column .post-image__details', 'color:' + theme.centerChannelColor, 2); diff --git a/web/sass-files/sass/partials/_markdown.scss b/web/sass-files/sass/partials/_markdown.scss index 241377252..8b0a32704 100644 --- a/web/sass-files/sass/partials/_markdown.scss +++ b/web/sass-files/sass/partials/_markdown.scss @@ -8,11 +8,14 @@ margin-left: 4px; } } -.markdown-inline-img { - -moz-force-broken-image-icon: 1; - max-height: 500px; - height: 500px; +#post-list { + .markdown-inline-img { + -moz-force-broken-image-icon: 1; + max-height: 500px; + height: 500px; + } } + .post-body { hr { height: 4px; diff --git a/web/sass-files/sass/partials/_popover.scss b/web/sass-files/sass/partials/_popover.scss index 430813e63..7d98935d5 100644 --- a/web/sass-files/sass/partials/_popover.scss +++ b/web/sass-files/sass/partials/_popover.scss @@ -36,10 +36,36 @@ } } + .search-autocomplete__divider { + margin: 10px 0 5px; + line-height: 21px; + position: relative; + &:first-child { + margin-top: 5px; + } + span { + display: inline-block; + padding-right: 10px; + background: #fff; + z-index: 5; + position: relative; + } + &:before { + content: ""; + position: absolute; + width: 100%; + height: 1px; + background: #ddd; + top: 10px; + left: 0; + @include opacity(0.2); + } + } + .search-autocomplete__item { cursor: pointer; padding: 6px 8px; - margin: 3px 0; + margin: 3px 0 0 5px; @include border-radius(2px); white-space: nowrap; overflow: hidden; diff --git a/web/sass-files/sass/partials/_post.scss b/web/sass-files/sass/partials/_post.scss index b57c51242..36f6f445e 100644 --- a/web/sass-files/sass/partials/_post.scss +++ b/web/sass-files/sass/partials/_post.scss @@ -674,7 +674,7 @@ body.ios { width: 20%; float: right; img { - height: 75px; + max-height: 75px; max-width: 100%; } } |