diff options
35 files changed, 274 insertions, 76 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index a9dad1798..0bbb2be93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,16 +1,31 @@ # Mattermost Changelog -## UNDER DEVELOPMENT Release v1.3.0 +## Release v1.3.0 -The "UNDER DEVELOPMENT" section of the Mattermost changelog appears in the product's `master` branch to note key changes committed to master and are on their way to the next stable release. When a stable release is pushed the "UNDER DEVELOPMENT" heading is removed from the final changelog of the release. +Release date: 2015-12-16 -- **Release candidate anticipated:** 2015-12-10 -- **Final release anticipated:** 2015-12-16 +### Release Highlights + +#### iOS App + +- New [Mattermost iOS App](https://github.com/mattermost/ios) now available for iPhone, iPad, and iPod Touch +- New [Mattermost Push Notification Service](https://github.com/mattermost/push-proxy) to relay notifications to custom iOS applications + +#### Search Upgrades + +- Jump to search results in archives using new message permalinks +- It's easier to find what you're looking for with improved auto-complete in search + +#### Advanced Formatting + +- Express more in symbols, with new emoji auto-complete +- Express more in numbers, with rendering of mathematical expressions using Latex (start code blocks with ```latex) +- Personalize your look with new custom font settings under **Account Settings** > **Display** > **Display Font** ### New Features Authentication -- Documented unofficial GitHub SSO support using GitLab UI +- Added unofficial SSO support for GitHub.com and GitHub Enterprise using GitLab UI Archives - Added permalink feature that lets users link to a post in the message archives @@ -35,13 +50,12 @@ Performance - Refactored the center channel Messaging & Comments -- Added "Help" link for messaging -- Removed the @all mention - Added Markdown support for task lists +- Added "Help" link for messaging - Added ability to preview a Markdown message before sending (enabled via Account Settings -> Advanced -> Preview pre-release features) Onboarding -- Added various small improvements to the tutorial +- Minor upgrades to tutorial User Interface - Visually combined sequential messages from the same user @@ -52,6 +66,7 @@ User Interface #### Bug Fixes +- Removed the @all mention to keep users from accidentally spamming team sites - Fixed bug where the member list only showed "20" members for channels with more than 20 members - Fixed bug where the channel sidebar didn't order correctly on Postgres databases - Fixed bug where search results did not highlight when searching with quotation marks, wildcard, or in: and from: modifiers @@ -124,7 +139,7 @@ To limit the impact of this security issue, Mattermost v1.2.0 has been removed f #### Syntax Highlighting -- Syntax highlight for code blocks now available for `Diff, Apache, Makefile, HTTP, JSON, Markdown, JavaScript, CSS, nginx, ObjectiveC, Python, XML, Perl, Bash, PHP, Coffee, C, SQL, Go, Ruby, Java, and ini` +- Syntax highlight for code blocks now available for `Diff, Apache, Makefile, HTTP, JSON, Markdown, JavaScript, CSS, nginx, ObjectiveC, Python, XML, Perl, Bash, PHP, CoffeeScript, C, SQL, Go, Ruby, Java, and ini` #### Usability Improvements @@ -161,7 +176,7 @@ User Interface - Member list in Channel display now scrollable, and includes Message button to message channel members directly - Added ability to edit previous message by hitting UP arrow - Syntax highlighting added for code blocks - - 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`. + - Languages include `Diff, Apache, Makefile, HTTP, JSON, Markdown, Java, CSS, nginx, ObjectiveC, Python, XML, Perl, Bash, PHP, CoffeeScript, 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 diff --git a/api/post.go b/api/post.go index a102cdf4d..6c1d4bbd1 100644 --- a/api/post.go +++ b/api/post.go @@ -642,9 +642,9 @@ func sendNotificationsAndForget(c *Context, post *model.Post, team *model.Team, msg.ServerId = utils.CfgDiagnosticId if channel.Type == model.CHANNEL_DIRECT { - msg.Message = channelName + " sent you a direct message" + msg.Message = senderName + " sent you a direct message" } else { - msg.Message = profileMap[id].FirstName + " mentioned you in " + channelName + msg.Message = senderName + " mentioned you in " + channelName } httpClient := http.Client{} @@ -1062,5 +1062,7 @@ func searchPosts(c *Context, w http.ResponseWriter, r *http.Request) { } } + w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") + w.Header().Set("Expires", "0") w.Write([]byte(posts.ToJson())) } diff --git a/config/config.json b/config/config.json index 4477ec63b..516b96dab 100644 --- a/config/config.json +++ b/config/config.json @@ -10,6 +10,7 @@ "EnablePostUsernameOverride": false, "EnablePostIconOverride": false, "EnableTesting": false, + "EnableDeveloper": false, "EnableSecurityFixAlert": true }, "TeamSettings": { diff --git a/doc/developer/Setup.md b/doc/developer/Setup.md index 24e7d6a90..fd3704545 100644 --- a/doc/developer/Setup.md +++ b/doc/developer/Setup.md @@ -58,8 +58,7 @@ Any issues? Please let us know on our forums at: http://forum.mattermost.org 1. `mkdir ~/go` 2. Add the following to your ~/.bashrc `export GOPATH=$HOME/go` - `export GOROOT=/usr/local/go` - `export PATH=$PATH:$GOROOT/bin` + `export PATH=$PATH:$GOPATH/bin` `ulimit -n 8096` If you don't increase the file handle limit you may see some weird build issues with browserify or npm. 3. Reload your bashrc @@ -81,3 +80,51 @@ Any issues? Please let us know on our forums at: http://forum.mattermost.org 10. If tests passed, you can now run Mattermost using `make run` Any issues? Please let us know on our forums at: http://forum.mattermost.org + +### Archlinux ### + +1. Install Docker + 1. `pacman -S docker` + 2. `gpasswd -a user docker` + 3. `systemctl enable docker.service` + 4. `systemctl start docker.service` + 5. `newgrp docker` +2. Set up your dockerhost address + 1. Edit your /etc/hosts file to include the following line + `127.0.0.1 dockerhost` +3. Install Go + 1. `pacman -S go` +4. Set up your Go workspace and add Go to the PATH + 1. `mkdir ~/go` + 2. Add the following to your ~/.bashrc + 1. `export GOPATH=$HOME/go` + 2. `export GOROOT=/usr/lib/go` + 3. `export PATH=$PATH:$GOROOT/bin` + 3. Reload your bashrc + `source ~/.bashrc` +4. Edit /etc/security/limits.conf and add the following lines (replace *username* with your user): + + ``` + username soft nofile 8096 + username hard nofile 8096 + ``` + + You will need to reboot after changing this. If you don't increase the file handle limit you may see some weird build issues with browserify or npm. +5. Install Node.js + `pacman -S nodejs npm` +6. Install Ruby and Compass + 1. `pacman -S ruby` + 2. Add executable gems to your path in your ~/.bashrc + + `PATH="$(ruby -e 'print Gem.user_dir')/bin:$PATH"` + 3. `gem install compass` +7. Download Mattermost + `cd ~/go` + `mkdir -p src/github.com/mattermost` + `cd src/github.com/mattermost` + `git clone https://github.com/mattermost/platform.git` + `cd platform` +8. Run unit tests on Mattermost using `make test` to make sure the installation was successful +9. If tests passed, you can now run Mattermost using `make run` + +Any issues? Please let us know on our forums at: http://forum.mattermost.org diff --git a/doc/developer/tests/test-syntax-highlighting.md b/doc/developer/tests/test-syntax-highlighting.md index 7f8f4cdaa..b1568c385 100644 --- a/doc/developer/tests/test-syntax-highlighting.md +++ b/doc/developer/tests/test-syntax-highlighting.md @@ -133,7 +133,7 @@ echo "Hello World" ### CoffeeScript -``` coffee +``` coffeescript console.log(“Hello world!”); ``` diff --git a/doc/help/Markdown.md b/doc/help/Markdown.md index 64ce4fc83..d185a4160 100644 --- a/doc/help/Markdown.md +++ b/doc/help/Markdown.md @@ -31,7 +31,7 @@ code block To add syntax highlighting, type the language to be highlighted after the ``` at the beginning of the code block. Supported languages are: -`diff, apache, makefile, http, json, markdown, javascript, css, nginx, objectivec, python, xml, perl, bash, php, coffee (CoffeeScript), cs (C#), cpp (C++), sql, go, ruby, java, ini, latex` +`diff, apache, makefile, http, json, markdown, javascript, css, nginx, objectivec, python, xml, perl, bash, php, coffeescript, cs (C#), cpp (C++), sql, go, ruby, java, ini, latex` Example: diff --git a/doc/help/Messaging.md b/doc/help/Messaging.md index 548892650..2063ad41c 100644 --- a/doc/help/Messaging.md +++ b/doc/help/Messaging.md @@ -1,18 +1,18 @@ # Messaging -## Writing Messages +### Writing Messages -You can write messages using the input box with the text "Write a message..." at the bottom of Mattermost. +You can write messages using the input box with the text "Write a message..." at the bottom of Mattermost. -Press **ENTER** to send a message. Use **Shift+ENTER** to create a new line without sending a message. +Press **ENTER** to send a message. Use **Shift+ENTER** to create a new line without sending a message. -## Formatting Messages +### Formatting Messages -Mattermost messages are formatted using a standard called "markdown". Here are examples: +Mattermost messages are formatted using a standard called "markdown". Here are examples: | Text Entered | How it appears | |:---------------|:---------------| -|`**bold**`| **bold** | +|`**bold**`| **bold** | | `_italic_`|_italic_| |`[hyperlink](http://mattermost.org)`|[hyperlink](http://mattermost.org)| |`![embedded image](https://travis-ci.org/mattermost/platform.svg)`|![embedded image](https://travis-ci.org/mattermost/platform.svg)| @@ -21,27 +21,27 @@ Mattermost messages are formatted using a standard called "markdown". Here are e Emojis provided free from [Emoji One](http://emojione.com/). Check out a full list of Emojis [here](http://emoji.codes/). -## Mentioning Teammates +### Mentioning Teammates -You can mention a teammate by using the `@` symbol plus their username to send them a special notification to draw their attention. +You can mention a teammate by using the `@` symbol plus their username to send them a special notification to draw their attention. -For example, you might write: +For example, you might write: ``` @alice how did your interview go with the new candidate? -``` +``` -Which sends a special mention notification to **alice** to check your message. +Which sends a special mention notification to **alice** to check your message. -To mention a teammate, press `@` and you should see a list of team members who can be messaged. You can either type their username or use the **Up** and **Down** arrow keys and then **ENTER** to select them to be mentioned. +To mention a teammate, press `@` and you should see a list of team members who can be messaged. You can either type their username or use the **Up** and **Down** arrow keys and then **ENTER** to select them to be mentioned. -You can configure how you'd like to be alerted about mentions of your username, your first name, your nickname, or other keywords from **Account Settings** > **Notifications** and you can set channel-specific preferences from **[Channel Name]** > **Notification Preferences** +You can configure how you'd like to be alerted about mentions of your username, your first name, your nickname, or other keywords from **Account Settings** > **Notifications** and you can set channel-specific preferences from **[Channel Name]** > **Notification Preferences** -## Messages Dropdown Menu +### Messages Dropdown Menu -To get to the Messages Dropdown Menu, hover over a message and click on the [...] menu. This shows a dropdown list containing additional actions you can perform on a message: +To get to the Messages Dropdown Menu, hover over a message and click on the [...] menu. This shows a dropdown list containing additional actions you can perform on a message: - **Reply:** Opens up the sidebar so you can reply to a message in a comment thread. -- **Permalink:** Creates a link to the message. Sharing this link with other users in the channel lets them view the linked message in the Message Archives. -- **Delete:** Deletes the message so it is no longer visible. Team Administrators and System Administrators can also delete another user's message. +- **Permalink:** Creates a link to the message. Sharing this link with other users in the channel lets them view the linked message in the Message Archives. +- **Delete:** Deletes the message so it is no longer visible. Team Administrators and System Administrators can also delete another user's message. - **Edit:** Lets you edit your own message. diff --git a/docker/1.3/Dockerfile b/docker/1.3/Dockerfile index 55b69673a..4a25198af 100644 --- a/docker/1.3/Dockerfile +++ b/docker/1.3/Dockerfile @@ -34,7 +34,7 @@ VOLUME /var/lib/mysql WORKDIR /mattermost # Copy over files -ADD https://github.com/mattermost/platform/releases/download/v1.3.0-rc1/mattermost.tar.gz / +ADD https://github.com/mattermost/platform/releases/download/v1.3.0/mattermost.tar.gz / RUN tar -zxvf /mattermost.tar.gz --strip-components=1 && rm /mattermost.tar.gz ADD config_docker.json / ADD docker-entry.sh / diff --git a/docker/dev/config_docker.json b/docker/dev/config_docker.json index ab1373a44..2c109c105 100644 --- a/docker/dev/config_docker.json +++ b/docker/dev/config_docker.json @@ -10,6 +10,7 @@ "EnablePostUsernameOverride": false, "EnablePostIconOverride": false, "EnableTesting": false, + "EnableDeveloper": false, "EnableSecurityFixAlert": true }, "TeamSettings": { diff --git a/docker/local/config_docker.json b/docker/local/config_docker.json index ab1373a44..2c109c105 100644 --- a/docker/local/config_docker.json +++ b/docker/local/config_docker.json @@ -10,6 +10,7 @@ "EnablePostUsernameOverride": false, "EnablePostIconOverride": false, "EnableTesting": false, + "EnableDeveloper": false, "EnableSecurityFixAlert": true }, "TeamSettings": { diff --git a/model/config.go b/model/config.go index 9030f91ae..06cb9829e 100644 --- a/model/config.go +++ b/model/config.go @@ -33,6 +33,7 @@ type ServiceSettings struct { EnablePostUsernameOverride bool EnablePostIconOverride bool EnableTesting bool + EnableDeveloper *bool EnableSecurityFixAlert *bool } @@ -191,6 +192,11 @@ func (o *Config) SetDefaults() { o.EmailSettings.PasswordResetSalt = NewRandomString(32) } + if o.ServiceSettings.EnableDeveloper == nil { + o.ServiceSettings.EnableDeveloper = new(bool) + *o.ServiceSettings.EnableDeveloper = false + } + if o.ServiceSettings.EnableSecurityFixAlert == nil { o.ServiceSettings.EnableSecurityFixAlert = new(bool) *o.ServiceSettings.EnableSecurityFixAlert = true diff --git a/utils/config.go b/utils/config.go index 0789c101d..3f451b88a 100644 --- a/utils/config.go +++ b/utils/config.go @@ -195,6 +195,7 @@ func getClientConfig(c *model.Config) map[string]string { props["EnableOutgoingWebhooks"] = strconv.FormatBool(c.ServiceSettings.EnableOutgoingWebhooks) props["EnablePostUsernameOverride"] = strconv.FormatBool(c.ServiceSettings.EnablePostUsernameOverride) props["EnablePostIconOverride"] = strconv.FormatBool(c.ServiceSettings.EnablePostIconOverride) + props["EnableDeveloper"] = strconv.FormatBool(*c.ServiceSettings.EnableDeveloper) props["SendEmailNotifications"] = strconv.FormatBool(c.EmailSettings.SendEmailNotifications) props["EnableSignUpWithEmail"] = strconv.FormatBool(c.EmailSettings.EnableSignUpWithEmail) diff --git a/web/react/components/admin_console/email_settings.jsx b/web/react/components/admin_console/email_settings.jsx index 238ace3da..42e3507d6 100644 --- a/web/react/components/admin_console/email_settings.jsx +++ b/web/react/components/admin_console/email_settings.jsx @@ -586,7 +586,7 @@ export default class EmailSettings extends React.Component { onChange={this.handleChange} disabled={!this.state.sendPushNotifications} /> - <p className='help-text'>{'Location of the push notification server.'}</p> + <p className='help-text'>{'Location of Mattermost push notification service you can set up behind your firewall using https://github.com/mattermost/push-proxy. For testing you can use https://push.mattermost.com, which connects to the sample Mattermost iOS app in the public Apple AppStore. Please do not use test service for production deployments.'}</p> </div> </div> diff --git a/web/react/components/admin_console/service_settings.jsx b/web/react/components/admin_console/service_settings.jsx index 1f5faf1d4..d7582d682 100644 --- a/web/react/components/admin_console/service_settings.jsx +++ b/web/react/components/admin_console/service_settings.jsx @@ -40,6 +40,7 @@ export default class ServiceSettings extends React.Component { config.ServiceSettings.EnablePostUsernameOverride = ReactDOM.findDOMNode(this.refs.EnablePostUsernameOverride).checked; config.ServiceSettings.EnablePostIconOverride = ReactDOM.findDOMNode(this.refs.EnablePostIconOverride).checked; config.ServiceSettings.EnableTesting = ReactDOM.findDOMNode(this.refs.EnableTesting).checked; + config.ServiceSettings.EnableDeveloper = ReactDOM.findDOMNode(this.refs.EnableDeveloper).checked; config.ServiceSettings.EnableSecurityFixAlert = ReactDOM.findDOMNode(this.refs.EnableSecurityFixAlert).checked; //config.ServiceSettings.EnableOAuthServiceProvider = ReactDOM.findDOMNode(this.refs.EnableOAuthServiceProvider).checked; @@ -343,6 +344,39 @@ export default class ServiceSettings extends React.Component { <div className='form-group'> <label className='control-label col-sm-4' + htmlFor='EnableDeveloper' + > + {'Enable Developer Mode: '} + </label> + <div className='col-sm-8'> + <label className='radio-inline'> + <input + type='radio' + name='EnableDeveloper' + value='true' + ref='EnableDeveloper' + defaultChecked={this.props.config.ServiceSettings.EnableDeveloper} + onChange={this.handleChange} + /> + {'true'} + </label> + <label className='radio-inline'> + <input + type='radio' + name='EnableDeveloper' + value='false' + defaultChecked={!this.props.config.ServiceSettings.EnableDeveloper} + onChange={this.handleChange} + /> + {'false'} + </label> + <p className='help-text'>{'(Developer Option) When true, extra information around errors will be displayed in the UI.'}</p> + </div> + </div> + + <div className='form-group'> + <label + className='control-label col-sm-4' htmlFor='EnableSecurityFixAlert' > {'Enable Security Alerts: '} diff --git a/web/react/components/posts_view.jsx b/web/react/components/posts_view.jsx index b7ac92672..cc4f5e138 100644 --- a/web/react/components/posts_view.jsx +++ b/web/react/components/posts_view.jsx @@ -233,7 +233,8 @@ export default class PostsView extends React.Component { window.requestAnimationFrame(() => { // If separator exists scroll to it. Otherwise scroll to bottom. if (this.refs.newMessageSeparator) { - this.refs.newMessageSeparator.scrollIntoView(); + var objDiv = this.refs.postlist; + objDiv.scrollTop = this.refs.newMessageSeparator.offsetTop; //scrolls node to top of Div } else { this.refs.postlist.scrollTop = this.refs.postlist.scrollHeight; } diff --git a/web/react/components/search_results_item.jsx b/web/react/components/search_results_item.jsx index f71abf971..f235cac0a 100644 --- a/web/react/components/search_results_item.jsx +++ b/web/react/components/search_results_item.jsx @@ -31,8 +31,7 @@ export default class SearchResultsItem extends React.Component { handleFocusRHSClick(e) { e.preventDefault(); - - EventHelpers.emitPostFocusRightHandSideEvent(this.props.post); + EventHelpers.emitPostFocusRightHandSideFromSearch(this.props.post, this.props.isMentionSearch); } render() { diff --git a/web/react/components/user_settings/custom_theme_chooser.jsx b/web/react/components/user_settings/custom_theme_chooser.jsx index 35f836adb..55242ca7f 100644 --- a/web/react/components/user_settings/custom_theme_chooser.jsx +++ b/web/react/components/user_settings/custom_theme_chooser.jsx @@ -3,6 +3,9 @@ import Constants from '../../utils/constants.jsx'; +const OverlayTrigger = ReactBootstrap.OverlayTrigger; +const Popover = ReactBootstrap.Popover; + export default class CustomThemeChooser extends React.Component { constructor(props) { super(props); @@ -19,6 +22,15 @@ export default class CustomThemeChooser extends React.Component { }); $('.color-picker').on('changeColor', this.onPickerChange); } + componentDidUpdate() { + const theme = this.props.theme; + Constants.THEME_ELEMENTS.forEach((element) => { + if (theme.hasOwnProperty(element.id) && element.id !== 'codeTheme') { + $('#' + element.id).data('colorpicker').color.setColor(theme[element.id]); + $('#' + element.id).colorpicker('update'); + } + }); + } onPickerChange(e) { const theme = this.props.theme; theme[e.target.id] = e.color.toHex(); @@ -72,6 +84,19 @@ export default class CustomThemeChooser extends React.Component { ); }); + var popoverContent = ( + <Popover + bsStyle='info' + id='code-popover' + className='code-popover' + > + <img + width='200' + src={'/static/images/themes/code_themes/' + theme[element.id] + 'Large.png'} + /> + </Popover> + ); + elements.push( <div className='col-sm-4 form-group' @@ -85,16 +110,22 @@ export default class CustomThemeChooser extends React.Component { <select className='form-control' type='text' - defaultValue={theme[element.id]} + value={theme[element.id]} onChange={this.onInputChange} > {codeThemeOptions} </select> + <OverlayTrigger + placement='top' + overlay={popoverContent} + ref='headerOverlay' + > <span className='input-group-addon'> <img src={'/static/images/themes/code_themes/' + theme[element.id] + '.png'} /> </span> + </OverlayTrigger> </div> </div> ); @@ -112,7 +143,7 @@ export default class CustomThemeChooser extends React.Component { <input className='form-control' type='text' - defaultValue={theme[element.id]} + value={theme[element.id]} onChange={this.onInputChange} /> <span className='input-group-addon'><i></i></span> diff --git a/web/react/dispatcher/event_helpers.jsx b/web/react/dispatcher/event_helpers.jsx index 297367ce9..a03923c1a 100644 --- a/web/react/dispatcher/event_helpers.jsx +++ b/web/react/dispatcher/event_helpers.jsx @@ -4,11 +4,11 @@ import AppDispatcher from '../dispatcher/app_dispatcher.jsx'; import ChannelStore from '../stores/channel_store.jsx'; import PostStore from '../stores/post_store.jsx'; +import SearchStore from '../stores/search_store.jsx'; import Constants from '../utils/constants.jsx'; const ActionTypes = Constants.ActionTypes; import * as AsyncClient from '../utils/async_client.jsx'; import * as Client from '../utils/client.jsx'; -import * as Utils from '../utils/utils.jsx'; export function emitChannelClickEvent(channel) { AsyncClient.getChannels(true); @@ -39,28 +39,27 @@ export function emitPostFocusEvent(postId) { ); } -export function emitPostFocusRightHandSideEvent(post) { +export function emitPostFocusRightHandSideFromSearch(post, isMentionSearch) { Client.getPost( post.channel_id, post.id, (data) => { AppDispatcher.handleServerAction({ type: ActionTypes.RECIEVED_POST_SELECTED, - post_list: data + post_list: data, + from_search: SearchStore.getSearchTerm() }); AppDispatcher.handleServerAction({ type: ActionTypes.RECIEVED_SEARCH, - results: null + results: null, + is_mention_search: isMentionSearch }); }, (err) => { AsyncClient.dispatchError(err, 'getPost'); } ); - - var postChannel = ChannelStore.get(post.channel_id); - Utils.switchChannel(postChannel); } export function emitLoadMorePostsEvent() { diff --git a/web/react/stores/browser_store.jsx b/web/react/stores/browser_store.jsx index ff6ae45ea..3417faaaf 100644 --- a/web/react/stores/browser_store.jsx +++ b/web/react/stores/browser_store.jsx @@ -29,6 +29,8 @@ class BrowserStoreClass { this.checkedLocalStorageSupported = ''; this.signalLogout = this.signalLogout.bind(this); this.isSignallingLogout = this.isSignallingLogout.bind(this); + this.signalLogin = this.signalLogin.bind(this); + this.isSignallingLogin = this.isSignallingLogin.bind(this); var currentVersion = sessionStorage.getItem('storage_version'); if (currentVersion !== global.window.mm_config.Version) { @@ -129,6 +131,21 @@ class BrowserStoreClass { return logoutId === sessionStorage.getItem('__logout__'); } + signalLogin() { + if (this.isLocalStorageSupported()) { + // PLT-1285 store an identifier in session storage so we can catch if the logout came from this tab on IE11 + const loginId = generateId(); + + sessionStorage.setItem('__login__', loginId); + localStorage.setItem('__login__', loginId); + localStorage.removeItem('__login__'); + } + } + + isSignallingLogin(loginId) { + return loginId === sessionStorage.getItem('__login__'); + } + /** * Preforms the given action on each item that has the given prefix * Signature for action is action(key, value) diff --git a/web/react/stores/error_store.jsx b/web/react/stores/error_store.jsx index 8fb051138..69d6cca7f 100644 --- a/web/react/stores/error_store.jsx +++ b/web/react/stores/error_store.jsx @@ -63,3 +63,4 @@ ErrorStore.dispatchToken = AppDispatcher.register((payload) => { }); export default ErrorStore; +window.ErrorStore = ErrorStore; diff --git a/web/react/utils/client.jsx b/web/react/utils/client.jsx index 5d02a8c88..beabf5227 100644 --- a/web/react/utils/client.jsx +++ b/web/react/utils/client.jsx @@ -246,6 +246,7 @@ export function loginByEmail(name, email, password, success, error) { data: JSON.stringify({name: name, email: email, password: password}), success: function onSuccess(data, textStatus, xhr) { track('api', 'api_users_login_success', data.team_id, 'email', data.email); + BrowserStore.signalLogin(); success(data, textStatus, xhr); }, error: function onError(xhr, status, err) { diff --git a/web/react/utils/constants.jsx b/web/react/utils/constants.jsx index d23c18b5d..5f027a409 100644 --- a/web/react/utils/constants.jsx +++ b/web/react/utils/constants.jsx @@ -166,29 +166,6 @@ export default { UPDATE_TYPING_MS: 5000, THEMES: { default: { - type: 'Mattermost', - sidebarBg: '#fafafa', - sidebarText: '#333333', - sidebarUnreadText: '#333333', - sidebarTextHoverBg: '#e6f2fa', - sidebarTextActiveBorder: '#378FD2', - sidebarTextActiveColor: '#111111', - sidebarHeaderBg: '#2389d7', - sidebarHeaderTextColor: '#ffffff', - onlineIndicator: '#7DBE00', - mentionBj: '#2389d7', - mentionColor: '#ffffff', - centerChannelBg: '#ffffff', - centerChannelColor: '#333333', - newMessageSeparator: '#FF8800', - linkColor: '#2389d7', - buttonBg: '#2389d7', - buttonColor: '#FFFFFF', - mentionHighlightBg: '#fff2bb', - mentionHighlightLink: '#2f81b7', - codeTheme: 'github' - }, - organization: { type: 'Organization', sidebarBg: '#2071a7', sidebarText: '#fff', @@ -211,6 +188,29 @@ export default { mentionHighlightLink: '#2f81b7', codeTheme: 'github' }, + mattermost: { + type: 'Mattermost', + sidebarBg: '#fafafa', + sidebarText: '#333333', + sidebarUnreadText: '#333333', + sidebarTextHoverBg: '#e6f2fa', + sidebarTextActiveBorder: '#378FD2', + sidebarTextActiveColor: '#111111', + sidebarHeaderBg: '#2389d7', + sidebarHeaderTextColor: '#ffffff', + onlineIndicator: '#7DBE00', + mentionBj: '#2389d7', + mentionColor: '#ffffff', + centerChannelBg: '#ffffff', + centerChannelColor: '#333333', + newMessageSeparator: '#FF8800', + linkColor: '#2389d7', + buttonBg: '#2389d7', + buttonColor: '#FFFFFF', + mentionHighlightBg: '#fff2bb', + mentionHighlightLink: '#2f81b7', + codeTheme: 'github' + }, mattermostDark: { type: 'Mattermost Dark', sidebarBg: '#1B2C3E', diff --git a/web/sass-files/sass/partials/_base.scss b/web/sass-files/sass/partials/_base.scss index 61ad186e0..4f9e1d5c7 100644 --- a/web/sass-files/sass/partials/_base.scss +++ b/web/sass-files/sass/partials/_base.scss @@ -9,6 +9,7 @@ body { -webkit-font-smoothing: antialiased; background: $body-bg; position: relative; + width: 100%; height: 100%; &.white { background: #fff; diff --git a/web/sass-files/sass/partials/_docs.scss b/web/sass-files/sass/partials/_docs.scss new file mode 100644 index 000000000..f4e7cc314 --- /dev/null +++ b/web/sass-files/sass/partials/_docs.scss @@ -0,0 +1,19 @@ +@charset "UTF-8"; + +.docs__page { + line-height: 1.7; + padding-bottom: 20px; + + > div { + width: 1170px; + margin: 0 auto; + padding: 0 15px; + max-width: 100%; + } + + h1.markdown__heading { + border-bottom: 1px solid #ddd; + padding-bottom: 1rem; + margin: 1em 0 1em; + } +}
\ No newline at end of file diff --git a/web/sass-files/sass/partials/_popover.scss b/web/sass-files/sass/partials/_popover.scss index bc55b7ff7..1ae07fe5b 100644 --- a/web/sass-files/sass/partials/_popover.scss +++ b/web/sass-files/sass/partials/_popover.scss @@ -10,6 +10,10 @@ display: inline-block; } +.code-popover .popover-content { + padding: 5px; +} + .user-popover__image { margin: 0 0 10px; @include border-radius(128px); diff --git a/web/sass-files/sass/partials/_post.scss b/web/sass-files/sass/partials/_post.scss index 3ec1c4434..fbebb4e98 100644 --- a/web/sass-files/sass/partials/_post.scss +++ b/web/sass-files/sass/partials/_post.scss @@ -209,6 +209,7 @@ body.ios { @include flex(1 1 auto); position: relative; overflow-y: hidden; + height: 100%; .post-list-holder-by-time { background: #fff; diff --git a/web/sass-files/sass/partials/_responsive.scss b/web/sass-files/sass/partials/_responsive.scss index 66aaede8d..2aa130fa9 100644 --- a/web/sass-files/sass/partials/_responsive.scss +++ b/web/sass-files/sass/partials/_responsive.scss @@ -54,9 +54,7 @@ @media screen and (max-width: 960px) { .sidebar--right { - width: 400px; z-index: 5; - right: 0; @include translateX(100%); &.move--left { diff --git a/web/sass-files/sass/partials/_sidebar--right.scss b/web/sass-files/sass/partials/_sidebar--right.scss index f328f0971..e39f7730b 100644 --- a/web/sass-files/sass/partials/_sidebar--right.scss +++ b/web/sass-files/sass/partials/_sidebar--right.scss @@ -1,17 +1,17 @@ @charset "UTF-8"; .sidebar--right { - position: absolute; + position: fixed; width: 400px; height: 100%; right: 0px; padding: 0; background: #fff; @include single-transition(transform, 0.5s, ease); - right: -320px; + @include translateX(400px); &.move--left { - right: 0; + @include translateX(0); } .post-body { diff --git a/web/sass-files/sass/styles.scss b/web/sass-files/sass/styles.scss index c93372175..7bf3574d2 100644 --- a/web/sass-files/sass/styles.scss +++ b/web/sass-files/sass/styles.scss @@ -49,6 +49,9 @@ // Responsive Css @import "partials/responsive"; +// Docs Css +@import "partials/docs"; + // Standalone Css @import "partials/oauth"; diff --git a/web/static/images/themes/code_themes/githubLarge.png b/web/static/images/themes/code_themes/githubLarge.png Binary files differnew file mode 100644 index 000000000..cffc6e012 --- /dev/null +++ b/web/static/images/themes/code_themes/githubLarge.png diff --git a/web/static/images/themes/code_themes/monokaiLarge.png b/web/static/images/themes/code_themes/monokaiLarge.png Binary files differnew file mode 100644 index 000000000..7224950af --- /dev/null +++ b/web/static/images/themes/code_themes/monokaiLarge.png diff --git a/web/static/images/themes/code_themes/solarized_darkLarge.png b/web/static/images/themes/code_themes/solarized_darkLarge.png Binary files differnew file mode 100644 index 000000000..582df48f9 --- /dev/null +++ b/web/static/images/themes/code_themes/solarized_darkLarge.png diff --git a/web/static/images/themes/code_themes/solarized_lightLarge.png b/web/static/images/themes/code_themes/solarized_lightLarge.png Binary files differnew file mode 100644 index 000000000..d2c2702fb --- /dev/null +++ b/web/static/images/themes/code_themes/solarized_lightLarge.png diff --git a/web/templates/docs.html b/web/templates/docs.html index 21659e810..0e0f51648 100644 --- a/web/templates/docs.html +++ b/web/templates/docs.html @@ -7,7 +7,7 @@ <div class="inner__wrap"> <div class="row content"> <div class="col-sm-12"> - <div id="docs"></div> + <div class="docs__page" id="docs"></div> </div> <div class="footer-push"></div> </div> diff --git a/web/templates/head.html b/web/templates/head.html index be4ed2b25..e80f0a24c 100644 --- a/web/templates/head.html +++ b/web/templates/head.html @@ -68,6 +68,16 @@ console.log('detected logout from a different tab'); window.location.href = '/' + window.mm_team.name; } + + if (e.originalEvent.key === '__login__' && e.originalEvent.storageArea === localStorage && e.originalEvent.newValue) { + // make sure it isn't this tab that is sending the logout signal (only necessary for IE11) + if (window.BrowserStore.isSignallingLogin(e.originalEvent.newValue)) { + return; + } + + console.log('detected login from a different tab'); + window.location.href = '/'; + } }); }); </script> @@ -85,6 +95,11 @@ type: 'POST', data: JSON.stringify(l) }); + + if (window.mm_config.EnableDeveloper === 'true') { + window.ErrorStore.storeLastError('DEVELOPER MODE: A javascript error has occured. Please use the javascript console to capture and report the error (row: ' + line + ' col: ' + column + ').'); + window.ErrorStore.emitChange(); + } } </script> |