summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile18
-rw-r--r--api/auto_constants.go4
-rw-r--r--api/auto_teams.go2
-rw-r--r--api/context.go8
-rw-r--r--api/file.go2
-rw-r--r--api/post.go2
-rw-r--r--api/team.go4
-rw-r--r--doc/developer/code-contribution.md4
-rw-r--r--model/channel_count.go2
-rw-r--r--store/sql_channel_store.go2
-rw-r--r--web/react/components/sidebar.jsx71
-rw-r--r--web/react/components/unread_channel_indicator.jsx35
-rw-r--r--web/react/components/user_settings_modal.jsx2
13 files changed, 110 insertions, 46 deletions
diff --git a/Makefile b/Makefile
index cd82c27a3..972ebe960 100644
--- a/Makefile
+++ b/Makefile
@@ -39,6 +39,15 @@ travis:
@echo Checking for style guide compliance
cd web/react && $(ESLINT) --quiet components/* dispatcher/* pages/* stores/* utils/*
+ @echo Running gofmt
+ $(eval GOFMT_OUTPUT := $(shell gofmt -d -s api/ model/ store/ utils/ manualtesting/ mattermost.go 2>&1))
+ @echo "$(GOFMT_OUTPUT)"
+ @if [ ! "$(GOFMT_OUTPUT)" ]; then \
+ echo "gofmt sucess"; \
+ else \
+ echo "gofmt failure"; \
+ exit 1; \
+ fi
@$(GO) build $(GOFLAGS) ./...
@$(GO) install $(GOFLAGS) ./...
@@ -108,6 +117,15 @@ install:
check: install
@echo Running ESLint...
-cd web/react && $(ESLINT) components/* dispatcher/* pages/* stores/* utils/*
+ @echo Running gofmt
+ $(eval GOFMT_OUTPUT := $(shell gofmt -d -s api/ model/ store/ utils/ manualtesting/ mattermost.go 2>&1))
+ @echo "$(GOFMT_OUTPUT)"
+ @if [[ ! "$(GOFMT_OUTPUT)" ]]; then \
+ echo "gofmt sucess"; \
+ else \
+ echo "gofmt failure"; \
+ exit 1; \
+ fi
test: install
@mkdir -p logs
diff --git a/api/auto_constants.go b/api/auto_constants.go
index f80f15f2d..73ecb47f8 100644
--- a/api/auto_constants.go
+++ b/api/auto_constants.go
@@ -12,8 +12,8 @@ const (
USER_PASSWORD = "passwd"
CHANNEL_TYPE = model.CHANNEL_OPEN
FUZZ_USER_EMAIL_PREFIX_LEN = 10
- BTEST_TEAM_DISPLAY_NAME = "TestTeam"
- BTEST_TEAM_NAME = "z-z-testdomaina"
+ BTEST_TEAM_DISPLAY_NAME = "TestTeam"
+ BTEST_TEAM_NAME = "z-z-testdomaina"
BTEST_TEAM_EMAIL = "test@nowhere.com"
BTEST_TEAM_TYPE = model.TEAM_OPEN
BTEST_USER_NAME = "Mr. Testing Tester"
diff --git a/api/auto_teams.go b/api/auto_teams.go
index e5c772b4c..dd82abe8d 100644
--- a/api/auto_teams.go
+++ b/api/auto_teams.go
@@ -52,7 +52,7 @@ func (cfg *AutoTeamCreator) createRandomTeam() (*model.Team, bool) {
}
team := &model.Team{
DisplayName: teamDisplayName,
- Name: teamName,
+ Name: teamName,
Email: teamEmail,
Type: model.TEAM_OPEN,
}
diff --git a/api/context.go b/api/context.go
index b1b4d2d10..5925c817f 100644
--- a/api/context.go
+++ b/api/context.go
@@ -439,10 +439,10 @@ func IsBetaDomain(r *http.Request) bool {
}
var privateIpAddress = []*net.IPNet{
- &net.IPNet{IP: net.IPv4(10, 0, 0, 1), Mask: net.IPv4Mask(255, 0, 0, 0)},
- &net.IPNet{IP: net.IPv4(176, 16, 0, 1), Mask: net.IPv4Mask(255, 255, 0, 0)},
- &net.IPNet{IP: net.IPv4(192, 168, 0, 1), Mask: net.IPv4Mask(255, 255, 255, 0)},
- &net.IPNet{IP: net.IPv4(127, 0, 0, 1), Mask: net.IPv4Mask(255, 255, 255, 252)},
+ {IP: net.IPv4(10, 0, 0, 1), Mask: net.IPv4Mask(255, 0, 0, 0)},
+ {IP: net.IPv4(176, 16, 0, 1), Mask: net.IPv4Mask(255, 255, 0, 0)},
+ {IP: net.IPv4(192, 168, 0, 1), Mask: net.IPv4Mask(255, 255, 255, 0)},
+ {IP: net.IPv4(127, 0, 0, 1), Mask: net.IPv4Mask(255, 255, 255, 252)},
}
func IsPrivateIpAddress(ipAddress string) bool {
diff --git a/api/file.go b/api/file.go
index 692558acf..c24775ee2 100644
--- a/api/file.go
+++ b/api/file.go
@@ -86,7 +86,7 @@ func uploadFile(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
- for i, _ := range files {
+ for i := range files {
file, err := files[i].Open()
defer file.Close()
if err != nil {
diff --git a/api/post.go b/api/post.go
index 005f3f884..21bc35b97 100644
--- a/api/post.go
+++ b/api/post.go
@@ -353,7 +353,7 @@ func fireAndForgetNotifications(post *model.Post, teamId, siteURL string) {
}
}
- for id, _ := range toEmailMap {
+ for id := range toEmailMap {
fireAndForgetMentionUpdate(post.ChannelId, id)
}
}
diff --git a/api/team.go b/api/team.go
index 44f86b160..92fcbff93 100644
--- a/api/team.go
+++ b/api/team.go
@@ -100,6 +100,10 @@ func createTeamFromSSO(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
+ if !isTreamCreationAllowed(c, team.Email) {
+ return
+ }
+
team.PreSave()
team.Name = model.CleanTeamName(team.Name)
diff --git a/doc/developer/code-contribution.md b/doc/developer/code-contribution.md
index 1a6537287..c796a82a5 100644
--- a/doc/developer/code-contribution.md
+++ b/doc/developer/code-contribution.md
@@ -23,8 +23,10 @@ git checkout -b <branch name>
## Programming and Testing
-1. Please review the [Mattermost Style Guide](developer/style-guide.md) prior to making changes.
+1. Please review the [Mattermost Style Guide](style-guide.md) prior to making changes.
+ To keep code clean and well structured, Mattermost uses ESLint to check that pull requests adhere to style guidelines for React. Code will need to follow Mattermost's React style guidelines in order to pass the automated build tests when a pull request is submitted.
+
2. Please make sure to thoroughly test your change before submitting a pull request.
## Submitting a Pull Request
diff --git a/model/channel_count.go b/model/channel_count.go
index d5daba14e..19d6ac150 100644
--- a/model/channel_count.go
+++ b/model/channel_count.go
@@ -20,7 +20,7 @@ type ChannelCounts struct {
func (o *ChannelCounts) Etag() string {
ids := []string{}
- for id, _ := range o.Counts {
+ for id := range o.Counts {
ids = append(ids, id)
}
sort.Strings(ids)
diff --git a/store/sql_channel_store.go b/store/sql_channel_store.go
index b58166fd6..3d1007874 100644
--- a/store/sql_channel_store.go
+++ b/store/sql_channel_store.go
@@ -440,7 +440,7 @@ func (s SqlChannelStore) GetExtraMembers(channelId string, limit int) StoreChann
if err != nil {
result.Err = model.NewAppError("SqlChannelStore.GetExtraMembers", "We couldn't get the extra info for channel members", "channel_id="+channelId+", "+err.Error())
} else {
- for i, _ := range members {
+ for i := range members {
members[i].Sanitize(utils.SanitizeOptions)
}
result.Data = members
diff --git a/web/react/components/sidebar.jsx b/web/react/components/sidebar.jsx
index 697fc09c9..87007edcc 100644
--- a/web/react/components/sidebar.jsx
+++ b/web/react/components/sidebar.jsx
@@ -13,6 +13,7 @@ var SidebarHeader = require('./sidebar_header.jsx');
var SearchBox = require('./search_bar.jsx');
var Constants = require('../utils/constants.jsx');
var NewChannelFlow = require('./new_channel_flow.jsx');
+var UnreadChannelIndicator = require('./unread_channel_indicator.jsx');
export default class Sidebar extends React.Component {
constructor(props) {
@@ -153,6 +154,16 @@ export default class Sidebar extends React.Component {
$(window).on('resize', this.onResize);
}
+ shouldComponentUpdate(nextProps, nextState) {
+ if (!Utils.areStatesEqual(nextProps, this.props)) {
+ return true;
+ }
+
+ if (!Utils.areStatesEqual(nextState, this.state)) {
+ return true;
+ }
+ return false;
+ }
componentDidUpdate() {
this.updateTitle();
this.updateUnreadIndicators();
@@ -274,15 +285,16 @@ export default class Sidebar extends React.Component {
this.updateUnreadIndicators();
}
updateUnreadIndicators() {
- var container = $(React.findDOMNode(this.refs.container));
+ const container = $(React.findDOMNode(this.refs.container));
+
+ var showTopUnread = false;
+ var showBottomUnread = false;
if (this.firstUnreadChannel) {
var firstUnreadElement = $(React.findDOMNode(this.refs[this.firstUnreadChannel]));
if (firstUnreadElement.position().top + firstUnreadElement.height() < 0) {
- $(React.findDOMNode(this.refs.topUnreadIndicator)).css('display', 'initial');
- } else {
- $(React.findDOMNode(this.refs.topUnreadIndicator)).css('display', 'none');
+ showTopUnread = true;
}
}
@@ -290,11 +302,14 @@ export default class Sidebar extends React.Component {
var lastUnreadElement = $(React.findDOMNode(this.refs[this.lastUnreadChannel]));
if (lastUnreadElement.position().top > container.height()) {
- $(React.findDOMNode(this.refs.bottomUnreadIndicator)).css('display', 'initial');
- } else {
- $(React.findDOMNode(this.refs.bottomUnreadIndicator)).css('display', 'none');
+ showBottomUnread = true;
}
}
+
+ this.setState({
+ showTopUnread,
+ showBottomUnread
+ });
}
createChannelElement(channel, index) {
var members = this.state.members;
@@ -432,19 +447,13 @@ export default class Sidebar extends React.Component {
this.lastUnreadChannel = null;
// create elements for all 3 types of channels
- var channelItems = this.state.channels.filter(
- function filterPublicChannels(channel) {
- return channel.type === 'O';
- }
- ).map(this.createChannelElement);
+ const publicChannels = this.state.channels.filter((channel) => channel.type === 'O');
+ const publicChannelItems = publicChannels.map(this.createChannelElement);
- var privateChannelItems = this.state.channels.filter(
- function filterPrivateChannels(channel) {
- return channel.type === 'P';
- }
- ).map(this.createChannelElement);
+ const privateChannels = this.state.channels.filter((channel) => channel.type === 'P');
+ const privateChannelItems = privateChannels.map(this.createChannelElement);
- var directMessageItems = this.state.showDirectChannels.map(this.createChannelElement);
+ const directMessageItems = this.state.showDirectChannels.map(this.createChannelElement);
// update the favicon to show if there are any notifications
var link = document.createElement('link');
@@ -498,20 +507,16 @@ export default class Sidebar extends React.Component {
/>
<SearchBox />
- <div
- ref='topUnreadIndicator'
- className='nav-pills__unread-indicator nav-pills__unread-indicator-top'
- style={{display: 'none'}}
- >
- Unread post(s) above
- </div>
- <div
- ref='bottomUnreadIndicator'
- className='nav-pills__unread-indicator nav-pills__unread-indicator-bottom'
- style={{display: 'none'}}
- >
- Unread post(s) below
- </div>
+ <UnreadChannelIndicator
+ show={this.state.showTopUnread}
+ extraClass='nav-pills__unread-indicator-top'
+ text={'Unread post(s) above'}
+ />
+ <UnreadChannelIndicator
+ show={this.state.showBottomUnread}
+ extraClass='nav-pills__unread-indicator-bottom'
+ text={'Unread post(s) below'}
+ />
<div
ref='container'
@@ -531,7 +536,7 @@ export default class Sidebar extends React.Component {
</a>
</h4>
</li>
- {channelItems}
+ {publicChannelItems}
<li>
<a
href='#'
diff --git a/web/react/components/unread_channel_indicator.jsx b/web/react/components/unread_channel_indicator.jsx
new file mode 100644
index 000000000..12a67633e
--- /dev/null
+++ b/web/react/components/unread_channel_indicator.jsx
@@ -0,0 +1,35 @@
+// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+// Indicator for the left sidebar which indicate if there's unread posts in a channel that is not shown
+// because it is either above or below the screen
+export default class UnreadChannelIndicator extends React.Component {
+ constructor(props) {
+ super(props);
+ }
+ render() {
+ let displayValue = 'none';
+ if (this.props.show) {
+ displayValue = 'initial';
+ }
+ return (
+ <div
+ className={'nav-pills__unread-indicator ' + this.props.extraClass}
+ style={{display: displayValue}}
+ >
+ {this.props.text}
+ </div>
+ );
+ }
+}
+
+UnreadChannelIndicator.defaultProps = {
+ show: false,
+ extraClass: '',
+ text: ''
+};
+UnreadChannelIndicator.propTypes = {
+ show: React.PropTypes.bool,
+ extraClass: React.PropTypes.string,
+ text: React.PropTypes.string
+};
diff --git a/web/react/components/user_settings_modal.jsx b/web/react/components/user_settings_modal.jsx
index 1daf6ebb9..67a4d0041 100644
--- a/web/react/components/user_settings_modal.jsx
+++ b/web/react/components/user_settings_modal.jsx
@@ -35,7 +35,7 @@ export default class UserSettingsModal extends React.Component {
tabs.push({name: 'security', uiName: 'Security', icon: 'glyphicon glyphicon-lock'});
tabs.push({name: 'notifications', uiName: 'Notifications', icon: 'glyphicon glyphicon-exclamation-sign'});
tabs.push({name: 'appearance', uiName: 'Appearance', icon: 'glyphicon glyphicon-wrench'});
- if (global.window.config.EnableOAuthServiceProvider) {
+ if (global.window.config.EnableOAuthServiceProvider === 'true') {
tabs.push({name: 'developer', uiName: 'Developer', icon: 'glyphicon glyphicon-th'});
}