diff --git a/Makefile b/Makefile index 222d4ffe4f..14a6ffc7d7 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,7 @@ GOFLAGS ?= $(GOFLAGS:) BUILD_NUMBER ?= $(BUILD_NUMBER:) GO=$(GOPATH)/bin/godep go +ESLINT=web/react/node_modules/eslint/bin/eslint.js ifeq ($(BUILD_NUMBER),) BUILD_NUMBER := dev @@ -62,6 +63,14 @@ install: @cd web/react/ && npm install +check: install + @echo Running ESLint... + @$(ESLINT) web/react/components/* + @$(ESLINT) web/react/dispatcher/* + @$(ESLINT) web/react/pages/* + @$(ESLINT) web/react/stores/* + @$(ESLINT) web/react/utils/* + test: install @mkdir -p logs @$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=180s ./api || exit 1 diff --git a/STYLE-GUIDE.md b/STYLE-GUIDE.md new file mode 100644 index 0000000000..e3fe2addfe --- /dev/null +++ b/STYLE-GUIDE.md @@ -0,0 +1,167 @@ +# Mattermost Style Guide + +1. [GO](#go) +2. [Javascript](#javascript) +3. [React-JSX](#react-jsx) + + +## Go + +All go code must follow the golang official [Style Guide](https://golang.org/doc/effective_go.html) + +In addition all code must be run though the official go formatter tool [gofmt](https://golang.org/cmd/gofmt/) + + +## Javascript + +Part of the build process is running ESLint. ESLint is the final authority on all style issues. PRs will not be accepted unless there are no errors or warnings running ESLint. The ESLint configuration file can be found in: [web/react/.eslintrc](https://github.com/mattermost/platform/blob/master/web/react/.eslintrc.json) + +Instructions on how to use ESLint with your favourite editor can be found here: [http://eslint.org/docs/user-guide/integrations](http://eslint.org/docs/user-guide/integrations) + +The following is an abridged version of the [Airbnb Javascript Style Guide](https://github.com/airbnb/javascript/blob/master/README.md#airbnb-javascript-style-guide-), with modifications. Anything that is unclear here follow that guide. If there is a conflict, follow what is said below. + +### Whitespace + +- Indentation is four spaces +- Use a space before the leading brace +- Use one space between the comma and the next argument in a bracketed list. No other space. +- Use whitespace to make code more readable. +- Do not use more than one newline to separate code blocks. +- Do not use a newline as the first line of a function + +```javascript +// Correct +function myFunction(parm1, parm2) { + stuff...; + + morestuff; +} + +// Incorrect +function myFunction ( parm1, parm2 ){ + stuff...; + + + morestuff; +} + +``` + +### Semicolons + +- You must use them always + +```javascript +// Correct +var x = 1; + +// Incorrect +var x = 1 +``` + +### Variables + +- Declarations must always use var, let or const. +- Prefer let or const over var. +- camelCase for all variable names. + +```javascript +// Correct +let myVariable = 4; + +// OK +var myVariable = 4; + +// Incorrect +myVariable = 4; +var my_variable = 4; +``` + +### Blocks + +- Braces must be used on all blocks. +- Braces must start on the same line as the statement starting the block. +- Else and else if must be on the same line as the if block closing brace. + +```javascript +// Correct +if (somthing) { + stuff...; +} else if (otherthing) { + stuff...; +} + +// Incorrect +if (somthing) +{ + stuff...; +} +else +{ + stuff...; +} + +// Incorrect +if (somthing) stuff...; +if (somthing) + stuff...; + +``` + +### Strings + +- Use template strings instead of concatenation. + +```javascript +// Correct +function getStr(stuff) { + return "This is the ${stuff} string"; +} + +// Incorrect +function wrongGetStr(stuff) { + return "This is the " + stuff + " string"; +} +``` + +## React-JSX + +Part of the build process is running ESLint. ESLint is the final authority on all style issues. PRs will not be accepted unless there are no errors or warnings running ESLint. The ESLint configuration file can be found in: [web/react/.eslintrc](https://github.com/mattermost/platform/blob/master/web/react/.eslintrc.json) + +Instructions on how to use ESLint with your favourite editor can be found here: [http://eslint.org/docs/user-guide/integrations](http://eslint.org/docs/user-guide/integrations) + +This is an abridged version of the [Airbnb React/JSX Style Guide](https://github.com/airbnb/javascript/tree/master/react#airbnb-reactjsx-style-guide). Anything that is unclear here follow that guide. If there is a conflict, follow what is said below. + +### General + +- Include only one React component per file. +- Use class \ extends React.Component over React.createClass unless you need mixins +- CapitalCamelCase with .jsx extension for component filenames. +- Filenames should be the component name. + +### Alignment + +- Follow alignment styles shown below: +```xml +// Correct + + + + +// Correct + +``` + +### Naming + +- Property names use camelCase. +- React component names use CapitalCamelCase. +- Do not use an understore for internal methods in a react component. + +```xml +// Correct + +``` diff --git a/api/team.go b/api/team.go index 1145e6e81c..c9fe42eccf 100644 --- a/api/team.go +++ b/api/team.go @@ -35,25 +35,18 @@ func signupTeam(c *Context, w http.ResponseWriter, r *http.Request) { m := model.MapFromJson(r.Body) email := strings.ToLower(strings.TrimSpace(m["email"])) - displayName := strings.TrimSpace(m["display_name"]) if len(email) == 0 { c.SetInvalidParam("signupTeam", "email") return } - if len(displayName) == 0 { - c.SetInvalidParam("signupTeam", "display_name") - return - } - subjectPage := NewServerTemplatePage("signup_team_subject", c.GetSiteURL()) bodyPage := NewServerTemplatePage("signup_team_body", c.GetSiteURL()) bodyPage.Props["TourUrl"] = utils.Cfg.TeamSettings.TourLink props := make(map[string]string) props["email"] = email - props["display_name"] = displayName props["time"] = fmt.Sprintf("%v", model.GetMillis()) data := model.MapToJson(props) diff --git a/web/react/.eslintrc b/web/react/.eslintrc new file mode 100644 index 0000000000..d8b36f6ca7 --- /dev/null +++ b/web/react/.eslintrc @@ -0,0 +1,139 @@ +{ + "ecmaFeatures": { + "jsx": true, + "blockBindings": true, + "modules": true + }, + "plugins": [ + "react" + ], + "env": { + "browser": true, + "node": true, + "jquery": true, + "es6": true + }, + "globals": { + "React": false + }, + "rules": { + "comma-dangle": [2, "never"], + "no-cond-assign": [2, "except-parens"], + "no-console": 1, + "no-constant-condition": 1, + "no-debugger": 1, + "no-dupe-args": 2, + "no-dupe-keys": 2, + "no-duplicate-case": 2, + "no-empty": 1, + "no-ex-assign": 1, + "no-extra-semi": 2, + "no-func-assign": 1, + "no-inner-declarations": 0, + "no-invalid-regexp": 2, + "no-irregular-whitespace": 2, + "no-unreachable": 2, + "valid-typeof": 2, + "no-unexpected-multiline": 2, + + "block-scoped-var": 1, + "complexity": [1, 8], + "consistent-return": 2, + "curly": [2, "all"], + "dot-notation": 2, + "dot-location": [2, "object"], + "eqeqeq": [2, "smart"], + "guard-for-in": 1, + "no-alert": 1, + "no-caller": 2, + "no-div-regex": 1, + "no-else-return": 1, + "no-eval": 2, + "no-extend-native": 2, + "no-floating-decimal": 2, + "no-labels": 2, + "no-lone-blocks": 1, + "no-multi-spaces": [2, { "exceptions": { "Property": false } }], + "no-multi-str": 0, + "no-param-reassign": 2, + "no-process-env": 2, + "no-redeclare": 2, + "no-return-assign": [2, "always"], + "no-script-url": 2, + "no-self-compare": 2, + "no-sequences": 2, + "no-throw-literal": 2, + "no-unused-expressions": 2, + "no-void": 2, + "no-warning-comments": 0, + "no-with": 2, + "radix": 2, + "vars-on-top": 0, + "wrap-iife": [2, "outside"], + "yoda": [2, "never", {"exceptRange": false, "onlyEquality": false}], + + "no-undefined": 2, + "no-shadow": [2, {"hoist": "functions"}], + "no-unused-vars": [2, {"vars": "all", "args": "all"}], + "no-use-before-define": [2, "nofunc"], + + // Style + "array-bracket-spacing": [2, "never"], + "brace-style": [2, "1tbs", { "allowSingleLine": false }], + "camelcase": [2, {"properties": "always"}], + "comma-spacing": [2, {"before": false, "after": true}], + "comma-style": [2, "last"], + "computed-property-spacing": [2, "never"], + "consistent-this": [2, "self"], + "func-names": 2, + "func-style": [2, "declaration"], + "indent": [2, 4, {"indentSwitchCase": false}], + "key-spacing": [2, {"beforeColon": false, "afterColon": true}], + "lines-around-comment": [2, { "beforeBlockComment": true, "beforeLineComment": true, "allowBlockStart": true, "allowBlockEnd": true }], + "linebreak-style": 2, + "new-cap": 2, + "new-parens": 2, + "no-lonely-if": 2, + "no-mixed-spaces-and-tabs": 2, + "no-multiple-empty-lines": [2, {"max": 1}], + "no-spaced-func": 2, + "no-ternary": 2, + "no-trailing-spaces": [2, { "skipBlankLines": false }], + "no-underscore-dangle": 2, + "no-unneeded-ternary": 2, + "object-curly-spacing": [2, "never"], + "one-var": [2, "never"], + "operator-linebreak": [2, "after"], + "padded-blocks": [2, "never"], + "quote-props": [2, "as-needed"], + "quotes": [2, "single", "avoid-escape"], + "semi-spacing": [2, {"before": false, "after": true}], + "semi": [2, "always"], + "space-after-keywords": [2, "always"], + "space-before-blocks": [2, "always"], + "space-before-function-paren": [2, "never"], + "space-in-parens": [2, "never"], + "space-infix-ops": 2, + "space-return-throw-case": 2, + "space-unary-ops": [2, { "words": true, "nonwords": false }], + "wrap-regex": 2, + + // React Specific + "react/display-name": [2, { "acceptTranspilerName": true }], + "react/jsx-boolean-value": [2, "always"], + "react/jsx-curly-spacing": [2, "never"], + "react/jsx-no-duplicate-props": [2, { "ignoreCase": false }], + "react/jsx-no-undef": 2, + "react/jsx-quotes": [2, "single", "avoid-escape"], + "react/jsx-uses-react": 2, + "react/jsx-uses-vars": 2, + "react/no-danger": 0, + "react/no-did-mount-set-state": 2, + "react/no-did-update-set-state": 2, + "react/no-multi-comp": 2, + "react/no-unknown-property": 2, + "react/prop-types": 2, + "react/sort-comp": 0, + "react/wrap-multilines": 2 + } +} diff --git a/web/react/components/delete_post_modal.jsx b/web/react/components/delete_post_modal.jsx index 11970bc2b3..f0cb809af0 100644 --- a/web/react/components/delete_post_modal.jsx +++ b/web/react/components/delete_post_modal.jsx @@ -98,7 +98,7 @@ module.exports = React.createClass({ : "" }
- +
diff --git a/web/react/components/file_preview.jsx b/web/react/components/file_preview.jsx index fdd12feec4..7c1db3e10a 100644 --- a/web/react/components/file_preview.jsx +++ b/web/react/components/file_preview.jsx @@ -24,7 +24,7 @@ module.exports = React.createClass({ if (filename.indexOf("/api/v1/files/get") != -1) { filename = filename.split("/api/v1/files/get")[1]; } - filename = window.location.origin + "/api/v1/files/get" + filename; + filename = utils.getWindowLocationOrigin() + "/api/v1/files/get" + filename; if (type === "image") { previews.push( diff --git a/web/react/components/login.jsx b/web/react/components/login.jsx index 05918650b1..fe0a47777b 100644 --- a/web/react/components/login.jsx +++ b/web/react/components/login.jsx @@ -103,13 +103,9 @@ module.exports = React.createClass({ return (
-
- { teamDisplayName } -
- /{ teamName }/ -
-
-
+
Sign in to:
+

{ teamDisplayName }

+

on { config.SiteName }

{ server_error } @@ -124,13 +120,13 @@ module.exports = React.createClass({
{ login_message } -
+ -
+
{"Want to create your own " + strings.Team + "?"} Sign up now
diff --git a/web/react/components/post_body.jsx b/web/react/components/post_body.jsx index 9f598ecb36..641ffeef27 100644 --- a/web/react/components/post_body.jsx +++ b/web/react/components/post_body.jsx @@ -32,7 +32,7 @@ module.exports = React.createClass({ if (fileInfo.path.indexOf("/api/v1/files/get") != -1) { fileInfo.path = fileInfo.path.split("/api/v1/files/get")[1]; } - fileInfo.path = window.location.origin + "/api/v1/files/get" + fileInfo.path; + fileInfo.path = utils.getWindowLocationOrigin() + "/api/v1/files/get" + fileInfo.path; if (type === "image") { $('').attr('src', fileInfo.path+'_thumb.jpg').load(function(path, name){ return function() { @@ -112,7 +112,7 @@ module.exports = React.createClass({ if (fileInfo.path.indexOf("/api/v1/files/get") != -1) { fileInfo.path = fileInfo.path.split("/api/v1/files/get")[1]; } - fileInfo.path = window.location.origin + "/api/v1/files/get" + fileInfo.path; + fileInfo.path = utils.getWindowLocationOrigin() + "/api/v1/files/get" + fileInfo.path; if (type === "image") { if (i < Constants.MAX_DISPLAY_FILES) { diff --git a/web/react/components/post_right.jsx b/web/react/components/post_right.jsx index 567be19621..8097a181e9 100644 --- a/web/react/components/post_right.jsx +++ b/web/react/components/post_right.jsx @@ -98,7 +98,7 @@ RootPost = React.createClass({ if (fileInfo.path.indexOf("/api/v1/files/get") != -1) { fileInfo.path = fileInfo.path.split("/api/v1/files/get")[1]; } - fileInfo.path = window.location.origin + "/api/v1/files/get" + fileInfo.path; + fileInfo.path = utils.getWindowLocationOrigin() + "/api/v1/files/get" + fileInfo.path; if (ftype === "image") { var url = fileInfo.path.replace(re1, '%20').replace(re2, '%28').replace(re3, '%29'); @@ -208,7 +208,7 @@ CommentPost = React.createClass({ if (fileInfo.path.indexOf("/api/v1/files/get") != -1) { fileInfo.path = fileInfo.path.split("/api/v1/files/get")[1]; } - fileInfo.path = window.location.origin + "/api/v1/files/get" + fileInfo.path; + fileInfo.path = utils.getWindowLocationOrigin() + "/api/v1/files/get" + fileInfo.path; if (type === "image") { var url = fileInfo.path.replace(re1, '%20').replace(re2, '%28').replace(re3, '%29'); diff --git a/web/react/components/sidebar_header.jsx b/web/react/components/sidebar_header.jsx index 5b442aeacc..e7512934a3 100644 --- a/web/react/components/sidebar_header.jsx +++ b/web/react/components/sidebar_header.jsx @@ -68,10 +68,10 @@ var NavbarDropdown = React.createClass({ for (var i = 0; i < this.state.teams.length; i++) { var teamName = this.state.teams[i]; - teams.push(
  • Switch to { teamName }
  • ); + teams.push(
  • Switch to { teamName }
  • ); } } - teams.push(
  • Create a New Team
  • ); + teams.push(
  • Create a New Team
  • ); return (
      diff --git a/web/react/components/signup_team.jsx b/web/react/components/signup_team.jsx index 362f791633..edd48e0b9b 100644 --- a/web/react/components/signup_team.jsx +++ b/web/react/components/signup_team.jsx @@ -20,21 +20,12 @@ module.exports = React.createClass({ state.email_error = ""; } - team.display_name = this.refs.name.getDOMNode().value.trim(); - if (!team.display_name) { - state.name_error = "This field is required"; - state.inValid = true; - } - else { - state.name_error = ""; - } - if (state.inValid) { this.setState(state); return; } - client.signupTeam(team.email, team.display_name, + client.signupTeam(team.email, function(data) { if (data["follow_link"]) { window.location.href = data["follow_link"]; @@ -55,7 +46,6 @@ module.exports = React.createClass({ render: function() { var email_error = this.state.email_error ? : null; - var name_error = this.state.name_error ? : null; var server_error = this.state.server_error ?
      : null; return ( @@ -64,15 +54,11 @@ module.exports = React.createClass({ { email_error }
    -
    - - { name_error } -
    { server_error }
    - +
    -
    + diff --git a/web/react/components/signup_team_complete.jsx b/web/react/components/signup_team_complete.jsx index 3e8a57308e..21f9edef14 100644 --- a/web/react/components/signup_team_complete.jsx +++ b/web/react/components/signup_team_complete.jsx @@ -42,11 +42,15 @@ WelcomePage = React.createClass({ state.email_error = ""; } - client.signupTeam(email, this.props.state.team.name, + client.signupTeam(email, function(data) { - this.props.state.wizard = "finished"; - this.props.updateParent(this.props.state); - window.location.href = "/signup_team_confirm/?email=" + encodeURI(email); + if (data["follow_link"]) { + window.location.href = data["follow_link"]; + } else { + this.props.state.wizard = "finished"; + this.props.updateParent(this.props.state); + window.location.href = "/signup_team_confirm/?email=" + encodeURIComponent(team.email); + } }.bind(this), function(err) { this.state.server_error = err.message; @@ -80,19 +84,25 @@ WelcomePage = React.createClass({

    -

    Welcome!

    -

    {"Let's set up your " + strings.Team + " on " + config.SiteName + "."}

    +

    Welcome to:

    +

    {config.SiteName}

    +

    Let's setup your new team

    Please confirm your email address:
    - { this.props.state.team.email }
    +

    +
    { this.props.state.team.email }
    +
    +

    +

    + Your account will administer the new team site.
    + You can add other administrators later.

    { storage_error }

    -

    If this is not correct, you can switch to a different email. We'll send you a new invite right away.

    @@ -105,7 +115,7 @@ WelcomePage = React.createClass({ { server_error }
    - + Use a different email
    ); } @@ -128,6 +138,7 @@ TeamDisplayNamePage = React.createClass({ this.props.state.wizard = "team_url"; this.props.state.team.display_name = display_name; + this.props.state.team.name = utils.cleanUpUrlable(display_name); this.props.updateParent(this.props.state); }, getInitialState: function() { @@ -158,9 +169,11 @@ TeamDisplayNamePage = React.createClass({
    { name_error }
    -

    {"Your " + strings.Team + " name shows in menus and headings. It may include the name of your " + strings.Company + ", but it's not required."}

    -   - +
    {"Name your " + strings.Team + " in any language. Your " + strings.Team + " name shows in menus and headings."}
    + +
    ); @@ -248,17 +261,23 @@ TeamURLPage = React.createClass({
    - { window.location.origin + "/" } + { utils.getWindowLocationOrigin() + "/" }
    { name_error }
    -

    {"Pick something short and memorable for your " + strings.Team + "'s web address."}

    -

    {"Your " + strings.Team + " URL can only contain lowercase letters, numbers and dashes. Also, it needs to start with a letter and cannot end in a dash."}

    -   - +

    {"Choose the web address of your new " + strings.Team + ":"}

    +
      +
    • Short and memorable is best
    • +
    • Use lower case letters, numbers and dashes
    • +
    • Must start with a letter and can't end in a dash
    • +
    + +
    + Back to previous step +
    ); @@ -461,14 +480,16 @@ SendInivtesPage = React.createClass({ return (
    - -

    Send Invitations

    - { emails } -
    -
     
    -
    -

    {"If you'd prefer, you can send invitations after you finish setting up the "+ strings.Team + "."}

    -
    Skip this step
    + +

    {"Invite " + utils.toTitleCase(strings.Team) + " Members"}

    + { emails } +
    Add Invitation
    +
    + +

    {"if you prefer, you can invite " + strings.Team + " members later"}
    and skip this step for now.

    +
    + Back to previous step +
    ); } @@ -512,19 +533,24 @@ UsernamePage = React.createClass({
    -

    Choose a username

    -
    -
    -
    - +

    Your username

    +
    {"Select a memorable username that makes it easy for " + strings.Team + "mates to identify you:"}
    +
    +
    +
    +
    +
    Choose your username
    + +
    Usernames must begin with a letter and contain 3 to 15 characters made up of lowercase letters, numbers, and the symbols '.', '-' and '_'
    +
    +
    + { name_error }
    - { name_error } + + -

    {"Pick something " + strings.Team + "mates will recognize. Your username is how you will appear to others."}

    -

    It can be made of lowercase letters and numbers.

    -   -
    ); @@ -542,15 +568,15 @@ PasswordPage = React.createClass({ var password = this.refs.password.getDOMNode().value.trim(); if (!password || password.length < 5) { - this.setState({name_error: "Please enter at least 5 characters"}); + this.setState({password_error: "Please enter at least 5 characters"}); return; } - this.setState({name_error: ""}); + this.setState({password_error: null, server_error: null}); $('#finish-button').button('loading'); var teamSignup = JSON.parse(JSON.stringify(this.props.state)); teamSignup.user.password = password; - teamSignup.user.allow_marketing = this.refs.email_service.getDOMNode().checked; + teamSignup.user.allow_marketing = true; delete teamSignup.wizard; var ctl = this; @@ -566,7 +592,7 @@ PasswordPage = React.createClass({ props.state.wizard = "finished"; props.updateParent(props.state, true); - window.location.href = window.location.origin + '/' + props.state.team.name + '/login?email=' + encodeURIComponent(teamSignup.team.email); + window.location.href = utils.getWindowLocationOrigin() + '/' + props.state.team.name + '/login?email=' + encodeURIComponent(teamSignup.team.email); // client.loginByEmail(teamSignup.team.domain, teamSignup.team.email, teamSignup.user.password, // function(data) { @@ -582,7 +608,7 @@ PasswordPage = React.createClass({ }, 5000); }.bind(this), function(err) { - this.setState({name_error: err.message}); + this.setState({server_error: err.message}); $('#sign-up-button').button('reset'); }.bind(this) ); @@ -594,30 +620,37 @@ PasswordPage = React.createClass({ client.track('signup', 'signup_team_07_password'); - var name_error = this.state.name_error ? : null; + var password_error = this.state.password_error ? : null; + var server_error = this.state.server_error ? : null; return (
    -

    Choose a password

    -

    You'll use your email address ({this.props.state.team.email}) and password to log into {config.SiteName}.

    -
    -
    -
    - +

    Your password

    +
    Select a password that you'll use to login with your email address:
    +
    +
    Email
    +
    {this.props.state.team.email}
    +
    +
    +
    +
    Choose your password
    + +
    Passwords must contain 5 to 50 characters. Your password will be strongest if it contains a mix of symbols, numbers, and upper and lowercase characters.
    +
    +
    + { password_error } + { server_error }
    -
    - { name_error } -
    -
    -
    -   - +

    By proceeding to create your account and use { config.SiteName }, you agree to our Terms of Service and Privacy Policy. If you do not agree, you cannot use {config.SiteName}.

    +
    ); @@ -640,9 +673,6 @@ module.exports = React.createClass({ props.wizard = "welcome"; props.team = {}; props.team.email = this.props.email; - props.team.display_name = this.props.name; - props.team.company_name = this.props.name; - props.team.name = utils.cleanUpUrlable(this.props.name); props.team.allowed_domains = ""; props.invites = []; props.invites.push(""); diff --git a/web/react/components/signup_user_complete.jsx b/web/react/components/signup_user_complete.jsx index bbf1f670c2..670aab943e 100644 --- a/web/react/components/signup_user_complete.jsx +++ b/web/react/components/signup_user_complete.jsx @@ -40,7 +40,7 @@ module.exports = React.createClass({ this.setState({name_error: "", email_error: "", password_error: "", server_error: ""}); - this.state.user.allow_marketing = this.refs.email_service.getDOMNode().checked; + this.state.user.allow_marketing = true; client.createUser(this.state.user, this.state.data, this.state.hash, function(data) { @@ -104,8 +104,8 @@ module.exports = React.createClass({ var yourEmailIs = this.state.user.email == "" ? "" : Your email address is { this.state.user.email }. var email = ( -
    - +
    +
    What's your email address?
    { email_error } @@ -124,29 +124,33 @@ module.exports = React.createClass({ return (
    -

    Signup to { config.SiteName }

    -
    - -
    +
    Welcome to:
    +

    { this.props.teamDisplayName }

    +

    on { config.SiteName }

    +

    Let's create your account

    { signup_message } - -
    - - { name_error } -

    Your username can be made of lowercase letters and numbers.

    -

    {"Pick something " + strings.Team + "mates will recognize. Your username is how you will appear to others"}

    -
    - { email } - -
    - - { password_error } -
    -

    { yourEmailIs } You’ll use this address to sign in to {config.SiteName}.

    -
    -

    +
    + { email } +

    { yourEmailIs } You’ll use this address to sign in to {config.SiteName}.

    +
    +
    Choose your username
    +
    + + { name_error } +

    Username must begin with a letter, and contain between 3 to 15 lowercase characters made up of numbers, letters, and the symbols '.', '-' and '_'"

    +
    +
    +
    +
    Choose your password
    +
    + + { password_error } +
    +
    +
    +

    { server_error } -

    By proceeding to create your account and use { config.SiteName }, you agree to our Terms of Service and Privacy Policy. If you do not agree, you cannot use {config.SiteName}.

    +

    By creating an account and using Mattermost you are agreeing to our Terms of Service. If you do not agree, you cannot use this service.

    ); } diff --git a/web/react/components/view_image.jsx b/web/react/components/view_image.jsx index c107de4d79..7b096c6298 100644 --- a/web/react/components/view_image.jsx +++ b/web/react/components/view_image.jsx @@ -40,7 +40,7 @@ module.exports = React.createClass({ if (fileInfo.path.indexOf("/api/v1/files/get") !== -1) { fileInfo.path = fileInfo.path.split("/api/v1/files/get")[1]; } - fileInfo.path = window.location.origin + "/api/v1/files/get" + fileInfo.path; + fileInfo.path = utils.getWindowLocationOrigin() + "/api/v1/files/get" + fileInfo.path; src = fileInfo['path'] + '_preview.jpg'; } @@ -148,7 +148,7 @@ module.exports = React.createClass({ if (info.path.indexOf("/api/v1/files/get") !== -1) { info.path = info.path.split("/api/v1/files/get")[1]; } - info.path = window.location.origin + "/api/v1/files/get" + info.path; + info.path = utils.getWindowLocationOrigin() + "/api/v1/files/get" + info.path; preview_filename = info['path'] + '_preview.jpg'; } @@ -166,7 +166,7 @@ module.exports = React.createClass({ if (download_link.indexOf("/api/v1/files/get") !== -1) { download_link = download_link.split("/api/v1/files/get")[1]; } - download_link = window.location.origin + "/api/v1/files/get" + download_link; + download_link = utils.getWindowLocationOrigin() + "/api/v1/files/get" + download_link; return (
    diff --git a/web/templates/signup_user_complete.html b/web/templates/signup_user_complete.html index 176ca77b14..e9f6bafcfb 100644 --- a/web/templates/signup_user_complete.html +++ b/web/templates/signup_user_complete.html @@ -7,7 +7,7 @@
    - diff --git a/web/web.go b/web/web.go index 1d59ef946e..68e2a5226f 100644 --- a/web/web.go +++ b/web/web.go @@ -219,7 +219,6 @@ func signupTeamComplete(c *api.Context, w http.ResponseWriter, r *http.Request) page := NewHtmlTemplatePage("signup_team_complete", "Complete Team Sign Up") page.Props["Email"] = props["email"] - page.Props["DisplayName"] = props["display_name"] page.Props["Data"] = data page.Props["Hash"] = hash page.Render(c, w)