summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/admin.go2
-rw-r--r--api/api_test.go1
-rw-r--r--api/context.go3
-rw-r--r--api/post.go22
-rw-r--r--api/templates/password_change_body.html2
-rw-r--r--api/templates/password_change_subject.html2
-rw-r--r--doc/developer/tests/test-links.md1
-rw-r--r--doc/help/Markdown.md2
-rw-r--r--i18n/en.json4
-rw-r--r--i18n/es.json10
-rw-r--r--model/utils.go40
-rw-r--r--web/react/components/rhs_thread.jsx12
-rw-r--r--web/react/utils/utils.jsx4
-rw-r--r--web/sass-files/sass/partials/_post.scss1
14 files changed, 87 insertions, 19 deletions
diff --git a/api/admin.go b/api/admin.go
index 61741b445..72a95ba6a 100644
--- a/api/admin.go
+++ b/api/admin.go
@@ -41,7 +41,7 @@ func getLogs(c *Context, w http.ResponseWriter, r *http.Request) {
file, err := os.Open(utils.GetLogFileLocation(utils.Cfg.LogSettings.FileLocation))
if err != nil {
- c.Err = model.NewAppError("getLogs", c.T("api.admin.file_read_error"), err.Error())
+ c.Err = model.NewLocAppError("getLogs", "api.admin.file_read_error", nil, err.Error())
}
defer file.Close()
diff --git a/api/api_test.go b/api/api_test.go
index 2ef4e196d..4d7192e4b 100644
--- a/api/api_test.go
+++ b/api/api_test.go
@@ -14,6 +14,7 @@ var Client *model.Client
func Setup() {
if Srv == nil {
utils.LoadConfig("config.json")
+ utils.InitTranslations()
utils.Cfg.TeamSettings.MaxUsersPerTeam = 50
NewServer()
StartServer()
diff --git a/api/context.go b/api/context.go
index b6ffb1a29..a3311a971 100644
--- a/api/context.go
+++ b/api/context.go
@@ -206,6 +206,7 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
if c.Err != nil {
+ c.Err.Translate(c.T)
c.Err.RequestId = c.RequestId
c.LogError(c.Err)
c.Err.Where = r.URL.Path
@@ -373,7 +374,7 @@ func (c *Context) RemoveSessionCookie(w http.ResponseWriter, r *http.Request) {
}
func (c *Context) SetInvalidParam(where string, name string) {
- c.Err = model.NewAppError(where, "Invalid "+name+" parameter", "")
+ c.Err = model.NewLocAppError(where, "api.context.invalid_param", map[string]interface{}{"Name": name}, "")
c.Err.StatusCode = http.StatusBadRequest
}
diff --git a/api/post.go b/api/post.go
index 7cd45d310..42c3c304d 100644
--- a/api/post.go
+++ b/api/post.go
@@ -185,6 +185,28 @@ func CreateWebhookPost(c *Context, channelId, text, overrideUsername, overrideIc
attachment["text"] = aText
list[i] = attachment
}
+ if _, ok := attachment["pretext"]; ok {
+ aText := attachment["pretext"].(string)
+ aText = linkWithTextRegex.ReplaceAllString(aText, "[${2}](${1})")
+ attachment["pretext"] = aText
+ list[i] = attachment
+ }
+ if fVal, ok := attachment["fields"]; ok {
+ if fields, ok := fVal.([]interface{}); ok {
+ // parse attachment field links into Markdown format
+ for j, fInt := range fields {
+ field := fInt.(map[string]interface{})
+ if _, ok := field["text"]; ok {
+ fText := field["text"].(string)
+ fText = linkWithTextRegex.ReplaceAllString(fText, "[${2}](${1})")
+ field["text"] = fText
+ fields[j] = field
+ }
+ }
+ attachment["fields"] = fields
+ list[i] = attachment
+ }
+ }
}
post.AddProp(key, list)
}
diff --git a/api/templates/password_change_body.html b/api/templates/password_change_body.html
index 82f4d5429..6199a3423 100644
--- a/api/templates/password_change_body.html
+++ b/api/templates/password_change_body.html
@@ -18,7 +18,7 @@
<tr>
<td style="border-bottom: 1px solid #ddd; padding: 0 0 20px;">
<h2 style="font-weight: normal; margin-top: 10px;">You updated your password</h2>
- <p>You updated your password for {{.Props.TeamDisplayName}} on {{ .Props.TeamURL }} by {{.Props.Method}}.<br>If this change wasn't initiated by you, please contact your system administrator.</p>
+ <p>Your password has been updated for {{.Props.TeamDisplayName}} on {{ .Props.TeamURL }} by {{.Props.Method}}.<br>If this change wasn't initiated by you, please contact your system administrator.</p>
</td>
</tr>
<tr>
diff --git a/api/templates/password_change_subject.html b/api/templates/password_change_subject.html
index e7a794090..0cbf052c1 100644
--- a/api/templates/password_change_subject.html
+++ b/api/templates/password_change_subject.html
@@ -1 +1 @@
-{{define "password_change_subject"}}You updated your password for {{.Props.TeamDisplayName}} on {{ .ClientCfg.SiteName }}{{end}}
+{{define "password_change_subject"}}Your password has been updated for {{.Props.TeamDisplayName}} on {{ .ClientCfg.SiteName }}{{end}}
diff --git a/doc/developer/tests/test-links.md b/doc/developer/tests/test-links.md
index 91e3e9403..b4a04e439 100644
--- a/doc/developer/tests/test-links.md
+++ b/doc/developer/tests/test-links.md
@@ -40,7 +40,6 @@ http://
./make-compiled-client.sh
test.:test
https://<your-mattermost-url>/signup/gitlab
-https://your-mattermost-url>/signup/gitlab
#### Only the links within these sentences should auto-link:
diff --git a/doc/help/Markdown.md b/doc/help/Markdown.md
index d185a4160..9d3cb2a90 100644
--- a/doc/help/Markdown.md
+++ b/doc/help/Markdown.md
@@ -88,7 +88,7 @@ and
## Emojis
-Emoji provided free by [Emoji One](http://emojione.com/). Check out a full list of emojis [here](http://http://emoji.codes/).
+Emoji provided free by [Emoji One](http://emojione.com/). Check out a full list of emojis [here](http://emoji.codes/).
```
:smile: :+1: :sheep:
diff --git a/i18n/en.json b/i18n/en.json
index 67cf9c31e..d1035e89a 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -10,5 +10,9 @@
{
"id": "api.admin.file_read_error",
"translation": "Error reading log file"
+ },
+ {
+ "id": "api.context.invalid_param",
+ "translation": "Invalid {{.Name}} parameter"
}
] \ No newline at end of file
diff --git a/i18n/es.json b/i18n/es.json
index 67cf9c31e..efa5b857b 100644
--- a/i18n/es.json
+++ b/i18n/es.json
@@ -1,14 +1,18 @@
[
{
"id": "utils.i18n.loaded",
- "translation": "Loaded system translations for '%v' from '%v'"
+ "translation": "Loaded system translations for '%v' from '%v' spanish test!"
},
{
"id": "mattermost.current_version",
- "translation": "Current version is %v (%v/%v/%v)"
+ "translation": "Current version is %v (%v/%v/%v) spanish test!"
},
{
"id": "api.admin.file_read_error",
- "translation": "Error reading log file"
+ "translation": "Error reading log file spanish test!"
+ },
+ {
+ "id": "api.context.invalid_param",
+ "translation": "Invalid {{.Name}} parameter spanish test!"
}
] \ No newline at end of file
diff --git a/model/utils.go b/model/utils.go
index 617c95efd..a18ca760e 100644
--- a/model/utils.go
+++ b/model/utils.go
@@ -9,13 +9,15 @@ import (
"encoding/base32"
"encoding/json"
"fmt"
- "github.com/pborman/uuid"
"io"
"net/mail"
"net/url"
"regexp"
"strings"
"time"
+
+ goi18n "github.com/nicksnyder/go-i18n/i18n"
+ "github.com/pborman/uuid"
)
type StringInterface map[string]interface{}
@@ -23,20 +25,31 @@ type StringMap map[string]string
type StringArray []string
type EncryptStringMap map[string]string
-// AppError is returned for any http response that's not in the 200 range.
type AppError struct {
- Message string `json:"message"` // Message to be display to the end user without debugging information
- DetailedError string `json:"detailed_error"` // Internal error string to help the developer
- RequestId string `json:"request_id"` // The RequestId that's also set in the header
- StatusCode int `json:"status_code"` // The http status code
- Where string `json:"-"` // The function where it happened in the form of Struct.Func
- IsOAuth bool `json:"is_oauth"` // Whether the error is OAuth specific
+ Id string `json:"id"`
+ Message string `json:"message"` // Message to be display to the end user without debugging information
+ DetailedError string `json:"detailed_error"` // Internal error string to help the developer
+ RequestId string `json:"request_id"` // The RequestId that's also set in the header
+ StatusCode int `json:"status_code"` // The http status code
+ Where string `json:"-"` // The function where it happened in the form of Struct.Func
+ IsOAuth bool `json:"is_oauth"` // Whether the error is OAuth specific
+ params map[string]interface{} `json:"-"`
}
func (er *AppError) Error() string {
return er.Where + ": " + er.Message + ", " + er.DetailedError
}
+func (er *AppError) Translate(T goi18n.TranslateFunc) {
+ if len(er.Message) == 0 {
+ if er.params == nil {
+ er.Message = T(er.Id)
+ } else {
+ er.Message = T(er.Id, er.params)
+ }
+ }
+}
+
func (er *AppError) ToJson() string {
b, err := json.Marshal(er)
if err != nil {
@@ -68,6 +81,17 @@ func NewAppError(where string, message string, details string) *AppError {
return ap
}
+func NewLocAppError(where string, id string, params map[string]interface{}, details string) *AppError {
+ ap := &AppError{}
+ ap.Id = id
+ ap.params = params
+ ap.Where = where
+ ap.DetailedError = details
+ ap.StatusCode = 500
+ ap.IsOAuth = false
+ return ap
+}
+
var encoding = base32.NewEncoding("ybndrfg8ejkmcpqxot1uwisza345h769")
// NewId is a globally unique identifier. It is a [A-Z0-9] string 26
diff --git a/web/react/components/rhs_thread.jsx b/web/react/components/rhs_thread.jsx
index 2edcd8b37..945b09e37 100644
--- a/web/react/components/rhs_thread.jsx
+++ b/web/react/components/rhs_thread.jsx
@@ -17,6 +17,8 @@ export default class RhsThread extends React.Component {
constructor(props) {
super(props);
+ this.mounted = false;
+
this.onChange = this.onChange.bind(this);
this.onChangeAll = this.onChangeAll.bind(this);
this.forceUpdateInfo = this.forceUpdateInfo.bind(this);
@@ -50,8 +52,11 @@ export default class RhsThread extends React.Component {
PostStore.addSelectedPostChangeListener(this.onChange);
PostStore.addChangeListener(this.onChangeAll);
PreferenceStore.addChangeListener(this.forceUpdateInfo);
+
this.resize();
window.addEventListener('resize', this.handleResize);
+
+ this.mounted = true;
}
componentDidUpdate() {
if ($('.post-right__scroll')[0]) {
@@ -63,7 +68,10 @@ export default class RhsThread extends React.Component {
PostStore.removeSelectedPostChangeListener(this.onChange);
PostStore.removeChangeListener(this.onChangeAll);
PreferenceStore.removeChangeListener(this.forceUpdateInfo);
+
window.removeEventListener('resize', this.handleResize);
+
+ this.mounted = false;
}
forceUpdateInfo() {
if (this.state.postList) {
@@ -82,7 +90,7 @@ export default class RhsThread extends React.Component {
}
onChange() {
var newState = this.getStateFromStores();
- if (!Utils.areObjectsEqual(newState, this.state)) {
+ if (this.mounted && !Utils.areObjectsEqual(newState, this.state)) {
this.setState(newState);
}
}
@@ -120,7 +128,7 @@ export default class RhsThread extends React.Component {
}
var newState = this.getStateFromStores();
- if (!Utils.areObjectsEqual(newState, this.state)) {
+ if (this.mounted && !Utils.areObjectsEqual(newState, this.state)) {
this.setState(newState);
}
}
diff --git a/web/react/utils/utils.jsx b/web/react/utils/utils.jsx
index 24042321f..db469952b 100644
--- a/web/react/utils/utils.jsx
+++ b/web/react/utils/utils.jsx
@@ -1309,6 +1309,10 @@ export function fillArray(value, length) {
// Checks if a data transfer contains files not text, folders, etc..
// Slightly modified from http://stackoverflow.com/questions/6848043/how-do-i-detect-a-file-is-being-dragged-rather-than-a-draggable-element-on-my-pa
export function isFileTransfer(files) {
+ if (isBrowserIE()) {
+ return files.types != null && files.types.contains('Files');
+ }
+
return files.types != null && (files.types.indexOf ? files.types.indexOf('Files') !== -1 : files.types.contains('application/x-moz-file'));
}
diff --git a/web/sass-files/sass/partials/_post.scss b/web/sass-files/sass/partials/_post.scss
index 7b7c2d73a..c5cd10b20 100644
--- a/web/sass-files/sass/partials/_post.scss
+++ b/web/sass-files/sass/partials/_post.scss
@@ -183,6 +183,7 @@ body.ios {
position: absolute;
top: 50%;
left: 50%;
+ pointer-events: none;
}
.overlay__files {