summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorge Goldberg <george@gberg.me>2017-03-17 16:29:26 +0000
committerGeorge Goldberg <george@gberg.me>2017-03-17 16:29:26 +0000
commit7f266c19511171f509ae8a60170de10c8d10b41e (patch)
tree04cd68ac4722313abec3ea47cc7cda229e463b1d
parentbfae88e60c7a623afae82e06ce1421ca778c06e7 (diff)
parent8568afe5b4fb4d26b14fbc0d21f088eaa490b314 (diff)
downloadchat-7f266c19511171f509ae8a60170de10c8d10b41e.tar.gz
chat-7f266c19511171f509ae8a60170de10c8d10b41e.tar.bz2
chat-7f266c19511171f509ae8a60170de10c8d10b41e.zip
Merge branch 'release-3.7' into master.
-rw-r--r--api/apitestlib.go2
-rw-r--r--api/channel.go16
-rw-r--r--api/oauth.go4
-rw-r--r--api/post.go4
-rw-r--r--api/team.go8
-rw-r--r--api/user.go6
-rw-r--r--api/webhook.go2
-rw-r--r--api4/apitestlib.go2
-rw-r--r--api4/channel.go6
-rw-r--r--api4/channel_test.go2
-rw-r--r--api4/post.go3
-rw-r--r--api4/team.go2
-rw-r--r--api4/user.go2
-rw-r--r--app/apptestlib.go4
-rw-r--r--app/channel.go51
-rw-r--r--app/command.go6
-rw-r--r--app/command_echo.go2
-rw-r--r--app/command_join.go2
-rw-r--r--app/command_loadtest.go4
-rw-r--r--app/command_msg.go2
-rw-r--r--app/import.go35
-rw-r--r--app/notification.go15
-rw-r--r--app/notification_test.go5
-rw-r--r--app/post.go56
-rw-r--r--app/slackimport.go41
-rw-r--r--app/team.go24
-rw-r--r--app/team_test.go11
-rw-r--r--app/user.go10
-rw-r--r--app/user_test.go6
-rw-r--r--app/webhook.go47
-rw-r--r--cmd/platform/channel.go2
-rw-r--r--cmd/platform/oldcommands.go6
-rw-r--r--cmd/platform/team.go3
-rw-r--r--einterfaces/saml.go2
-rw-r--r--i18n/de.json28
-rw-r--r--i18n/en.json4
-rw-r--r--i18n/es.json4
-rw-r--r--i18n/fr.json366
-rw-r--r--i18n/ja.json4
-rw-r--r--i18n/ko.json4
-rw-r--r--i18n/nl.json4
-rw-r--r--i18n/pt-BR.json30
-rw-r--r--i18n/ru.json4
-rw-r--r--i18n/zh-CN.json (renamed from i18n/zh_CN.json)4
-rw-r--r--i18n/zh-TW.json (renamed from i18n/zh_TW.json)4
-rw-r--r--model/command_response.go30
-rw-r--r--model/command_response_test.go65
-rw-r--r--model/incoming_webhook.go46
-rw-r--r--model/incoming_webhook_test.go31
-rw-r--r--model/slack_attachment.go29
-rw-r--r--web/web_test.go2
-rw-r--r--webapp/actions/channel_actions.jsx29
-rw-r--r--webapp/actions/global_actions.jsx4
-rw-r--r--webapp/actions/user_actions.jsx4
-rw-r--r--webapp/actions/websocket_actions.jsx20
-rw-r--r--webapp/components/access_history_modal.jsx1
-rw-r--r--webapp/components/activity_log_modal.jsx5
-rw-r--r--webapp/components/admin_console/team_users.jsx5
-rw-r--r--webapp/components/channel_invite_modal.jsx5
-rw-r--r--webapp/components/create_comment.jsx2
-rw-r--r--webapp/components/error_bar.jsx2
-rw-r--r--webapp/components/login/login_controller.jsx4
-rw-r--r--webapp/components/member_list_channel.jsx5
-rw-r--r--webapp/components/member_list_team.jsx9
-rw-r--r--webapp/components/more_channels.jsx5
-rw-r--r--webapp/components/needs_team.jsx4
-rw-r--r--webapp/components/post_view/components/post.jsx4
-rw-r--r--webapp/i18n/de.json36
-rw-r--r--webapp/i18n/en.json14
-rw-r--r--webapp/i18n/es.json12
-rw-r--r--webapp/i18n/fr.json288
-rw-r--r--webapp/i18n/i18n.jsx4
-rw-r--r--webapp/i18n/ja.json12
-rw-r--r--webapp/i18n/ko.json12
-rw-r--r--webapp/i18n/nl.json12
-rw-r--r--webapp/i18n/pt-BR.json42
-rw-r--r--webapp/i18n/ru.json12
-rw-r--r--webapp/i18n/zh-CN.json (renamed from webapp/i18n/zh_CN.json)12
-rw-r--r--webapp/i18n/zh-TW.json (renamed from webapp/i18n/zh_TW.json)12
-rw-r--r--webapp/sass/components/_modal.scss2
-rw-r--r--webapp/sass/components/_multi-select.scss1
-rw-r--r--webapp/sass/layout/_markdown.scss7
-rw-r--r--webapp/sass/layout/_post.scss16
-rw-r--r--webapp/sass/responsive/_mobile.scss10
-rw-r--r--webapp/sass/routes/_signup.scss3
-rw-r--r--webapp/stores/channel_store.jsx4
-rw-r--r--webapp/stores/notification_store.jsx4
-rw-r--r--webapp/utils/async_client.jsx41
-rw-r--r--webapp/utils/constants.jsx4
-rw-r--r--webapp/utils/post_utils.jsx4
-rw-r--r--webapp/utils/utils.jsx14
91 files changed, 939 insertions, 799 deletions
diff --git a/api/apitestlib.go b/api/apitestlib.go
index 4206d033e..89a65518a 100644
--- a/api/apitestlib.go
+++ b/api/apitestlib.go
@@ -158,7 +158,7 @@ func (me *TestHelper) CreateUser(client *model.Client) *model.User {
func LinkUserToTeam(user *model.User, team *model.Team) {
utils.DisableDebugLogForTest()
- err := app.JoinUserToTeam(team, user)
+ err := app.JoinUserToTeam(team, user, utils.GetSiteURL())
if err != nil {
l4g.Error(err.Error())
l4g.Close()
diff --git a/api/channel.go b/api/channel.go
index 0db3499e0..d408e9478 100644
--- a/api/channel.go
+++ b/api/channel.go
@@ -207,7 +207,7 @@ func updateChannel(c *Context, w http.ResponseWriter, r *http.Request) {
return
} else {
if oldChannelDisplayName != channel.DisplayName {
- if err := app.PostUpdateChannelDisplayNameMessage(c.Session.UserId, channel.Id, c.TeamId, oldChannelDisplayName, channel.DisplayName); err != nil {
+ if err := app.PostUpdateChannelDisplayNameMessage(c.Session.UserId, channel.Id, c.TeamId, oldChannelDisplayName, channel.DisplayName, c.GetSiteURL()); err != nil {
l4g.Error(err.Error())
}
}
@@ -255,7 +255,7 @@ func updateChannelHeader(c *Context, w http.ResponseWriter, r *http.Request) {
c.Err = err
return
} else {
- if err := app.PostUpdateChannelHeaderMessage(c.Session.UserId, channel.Id, c.TeamId, oldChannelHeader, channelHeader); err != nil {
+ if err := app.PostUpdateChannelHeaderMessage(c.Session.UserId, channel.Id, c.TeamId, oldChannelHeader, channelHeader, c.GetSiteURL()); err != nil {
l4g.Error(err.Error())
}
c.LogAudit("name=" + channel.Name)
@@ -301,7 +301,7 @@ func updateChannelPurpose(c *Context, w http.ResponseWriter, r *http.Request) {
c.Err = err
return
} else {
- if err := app.PostUpdateChannelPurposeMessage(c.Session.UserId, channel.Id, c.TeamId, oldChannelPurpose, channelPurpose); err != nil {
+ if err := app.PostUpdateChannelPurposeMessage(c.Session.UserId, channel.Id, c.TeamId, oldChannelPurpose, channelPurpose, c.GetSiteURL()); err != nil {
l4g.Error(err.Error())
}
c.LogAudit("name=" + channel.Name)
@@ -412,7 +412,7 @@ func join(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
- if err = app.JoinChannel(channel, c.Session.UserId); err != nil {
+ if err = app.JoinChannel(channel, c.Session.UserId, c.GetSiteURL()); err != nil {
c.Err = err
return
}
@@ -425,7 +425,7 @@ func leave(c *Context, w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
id := params["channel_id"]
- err := app.LeaveChannel(id, c.Session.UserId)
+ err := app.LeaveChannel(id, c.Session.UserId, c.GetSiteURL())
if err != nil {
c.Err = err
return
@@ -467,7 +467,7 @@ func deleteChannel(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
- err = app.DeleteChannel(channel, c.Session.UserId)
+ err = app.DeleteChannel(channel, c.Session.UserId, c.GetSiteURL())
if err != nil {
c.Err = err
return
@@ -663,7 +663,7 @@ func addMember(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
- go app.PostAddToChannelMessage(oUser, nUser, channel)
+ go app.PostAddToChannelMessage(oUser, nUser, channel, c.GetSiteURL())
app.UpdateChannelLastViewedAt([]string{id}, oUser.Id)
w.Write([]byte(cm.ToJson()))
@@ -698,7 +698,7 @@ func removeMember(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
- if err = app.RemoveUserFromChannel(userIdToRemove, c.Session.UserId, channel); err != nil {
+ if err = app.RemoveUserFromChannel(userIdToRemove, c.Session.UserId, channel, c.GetSiteURL()); err != nil {
c.Err = err
return
}
diff --git a/api/oauth.go b/api/oauth.go
index 659d5c129..25d4a89f9 100644
--- a/api/oauth.go
+++ b/api/oauth.go
@@ -285,7 +285,7 @@ func completeOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
action := props["action"]
switch action {
case model.OAUTH_ACTION_SIGNUP:
- if user, err := app.CreateOAuthUser(service, body, teamId); err != nil {
+ if user, err := app.CreateOAuthUser(service, body, teamId, c.GetSiteURL()); err != nil {
c.Err = err
} else {
doLogin(c, w, r, user, "")
@@ -297,7 +297,7 @@ func completeOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
case model.OAUTH_ACTION_LOGIN:
user := LoginByOAuth(c, w, r, service, body)
if len(teamId) > 0 {
- c.Err = app.AddUserToTeamByTeamId(teamId, user)
+ c.Err = app.AddUserToTeamByTeamId(teamId, user, c.GetSiteURL())
}
if c.Err == nil {
if val, ok := props["redirect_to"]; ok {
diff --git a/api/post.go b/api/post.go
index d6de65e40..4944ad28f 100644
--- a/api/post.go
+++ b/api/post.go
@@ -60,7 +60,7 @@ func createPost(c *Context, w http.ResponseWriter, r *http.Request) {
post.CreateAt = 0
}
- rp, err := app.CreatePostAsUser(post)
+ rp, err := app.CreatePostAsUser(post, c.GetSiteURL())
if err != nil {
c.Err = err
return
@@ -339,7 +339,7 @@ func getPermalinkTmp(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
- if list, err := app.GetPermalinkPost(postId, c.Session.UserId); err != nil {
+ if list, err := app.GetPermalinkPost(postId, c.Session.UserId, c.GetSiteURL()); err != nil {
c.Err = err
return
} else if HandleEtag(list.Etag(), "Get Permalink TMP", w, r) {
diff --git a/api/team.go b/api/team.go
index 3d6f18714..dda3b9d9d 100644
--- a/api/team.go
+++ b/api/team.go
@@ -61,7 +61,7 @@ func createTeam(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
- rteam, err := app.CreateTeamWithUser(team, c.Session.UserId)
+ rteam, err := app.CreateTeamWithUser(team, c.Session.UserId, c.GetSiteURL())
if err != nil {
c.Err = err
return
@@ -153,7 +153,7 @@ func addUserToTeam(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
- if _, err := app.AddUserToTeam(c.TeamId, userId); err != nil {
+ if _, err := app.AddUserToTeam(c.TeamId, userId, c.GetSiteURL()); err != nil {
c.Err = err
return
}
@@ -195,9 +195,9 @@ func addUserToTeamFromInvite(c *Context, w http.ResponseWriter, r *http.Request)
var err *model.AppError
if len(hash) > 0 {
- team, err = app.AddUserToTeamByHash(c.Session.UserId, hash, data)
+ team, err = app.AddUserToTeamByHash(c.Session.UserId, hash, data, c.GetSiteURL())
} else if len(inviteId) > 0 {
- team, err = app.AddUserToTeamByInviteId(inviteId, c.Session.UserId)
+ team, err = app.AddUserToTeamByInviteId(inviteId, c.Session.UserId, c.GetSiteURL())
} else {
c.Err = model.NewLocAppError("addUserToTeamFromInvite", "api.user.create_user.signup_link_invalid.app_error", nil, "")
return
diff --git a/api/user.go b/api/user.go
index 0c268b338..24a9025e4 100644
--- a/api/user.go
+++ b/api/user.go
@@ -89,7 +89,7 @@ func createUser(c *Context, w http.ResponseWriter, r *http.Request) {
var ruser *model.User
var err *model.AppError
if len(hash) > 0 {
- ruser, err = app.CreateUserWithHash(user, hash, r.URL.Query().Get("d"))
+ ruser, err = app.CreateUserWithHash(user, hash, r.URL.Query().Get("d"), c.GetSiteURL())
} else if len(inviteId) > 0 {
ruser, err = app.CreateUserWithInviteId(user, inviteId, c.GetSiteURL())
} else {
@@ -158,7 +158,7 @@ func LoginByOAuth(c *Context, w http.ResponseWriter, r *http.Request, service st
var err *model.AppError
if user, err = app.GetUserByAuth(&authData, service); err != nil {
if err.Id == store.MISSING_AUTH_ACCOUNT_ERROR {
- if user, err = app.CreateOAuthUser(service, bytes.NewReader(buf.Bytes()), ""); err != nil {
+ if user, err = app.CreateOAuthUser(service, bytes.NewReader(buf.Bytes()), "", c.GetSiteURL()); err != nil {
c.Err = err
return nil
}
@@ -1411,7 +1411,7 @@ func completeSaml(c *Context, w http.ResponseWriter, r *http.Request) {
relayProps = model.MapFromJson(strings.NewReader(stateStr))
}
- if user, err := samlInterface.DoLogin(encodedXML, relayProps); err != nil {
+ if user, err := samlInterface.DoLogin(encodedXML, relayProps, c.GetSiteURL()); err != nil {
c.Err = err
c.Err.StatusCode = http.StatusFound
return
diff --git a/api/webhook.go b/api/webhook.go
index 12751943e..a86af98c0 100644
--- a/api/webhook.go
+++ b/api/webhook.go
@@ -374,7 +374,7 @@ func incomingWebhook(c *Context, w http.ResponseWriter, r *http.Request) {
parsedRequest := model.IncomingWebhookRequestFromJson(payload)
- err := app.HandleIncomingWebhook(id, parsedRequest)
+ err := app.HandleIncomingWebhook(id, parsedRequest, c.GetSiteURL())
if err != nil {
c.Err = err
return
diff --git a/api4/apitestlib.go b/api4/apitestlib.go
index fbad3d6be..64d3f22b2 100644
--- a/api4/apitestlib.go
+++ b/api4/apitestlib.go
@@ -327,7 +327,7 @@ func (me *TestHelper) UpdateActiveUser(user *model.User, active bool) {
func LinkUserToTeam(user *model.User, team *model.Team) {
utils.DisableDebugLogForTest()
- err := app.JoinUserToTeam(team, user)
+ err := app.JoinUserToTeam(team, user, utils.GetSiteURL())
if err != nil {
l4g.Error(err.Error())
l4g.Close()
diff --git a/api4/channel.go b/api4/channel.go
index 5ed63320b..bd1710975 100644
--- a/api4/channel.go
+++ b/api4/channel.go
@@ -131,7 +131,7 @@ func updateChannel(c *Context, w http.ResponseWriter, r *http.Request) {
return
} else {
if oldChannelDisplayName != channel.DisplayName {
- if err := app.PostUpdateChannelDisplayNameMessage(c.Session.UserId, channel.Id, c.Params.TeamId, oldChannelDisplayName, channel.DisplayName); err != nil {
+ if err := app.PostUpdateChannelDisplayNameMessage(c.Session.UserId, channel.Id, c.Params.TeamId, oldChannelDisplayName, channel.DisplayName, c.GetSiteURL()); err != nil {
l4g.Error(err.Error())
}
}
@@ -302,7 +302,7 @@ func deleteChannel(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
- err = app.DeleteChannel(channel, c.Session.UserId)
+ err = app.DeleteChannel(channel, c.Session.UserId, c.GetSiteURL())
if err != nil {
c.Err = err
return
@@ -521,7 +521,7 @@ func removeChannelMember(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
- if err = app.RemoveUserFromChannel(c.Params.UserId, c.Session.UserId, channel); err != nil {
+ if err = app.RemoveUserFromChannel(c.Params.UserId, c.Session.UserId, channel, c.GetSiteURL()); err != nil {
c.Err = err
return
}
diff --git a/api4/channel_test.go b/api4/channel_test.go
index bf7218f0b..6d5b5cef3 100644
--- a/api4/channel_test.go
+++ b/api4/channel_test.go
@@ -426,7 +426,7 @@ func TestDeleteChannel(t *testing.T) {
if ch, err := app.GetChannel(publicChannel1.Id); err == nil && ch.DeleteAt == 0 {
t.Fatal("should have failed to get deleted channel")
- } else if err := app.JoinChannel(ch, user2.Id); err == nil {
+ } else if err := app.JoinChannel(ch, user2.Id, ""); err == nil {
t.Fatal("should have failed to join deleted channel")
}
diff --git a/api4/post.go b/api4/post.go
index 4632cb6df..a43f2f20f 100644
--- a/api4/post.go
+++ b/api4/post.go
@@ -45,7 +45,7 @@ func createPost(c *Context, w http.ResponseWriter, r *http.Request) {
post.CreateAt = 0
}
- rp, err := app.CreatePostAsUser(post)
+ rp, err := app.CreatePostAsUser(post, c.GetSiteURL())
if err != nil {
c.Err = err
return
@@ -224,4 +224,3 @@ func getFileInfosForPost(c *Context, w http.ResponseWriter, r *http.Request) {
w.Write([]byte(model.FileInfosToJson(infos)))
}
}
-
diff --git a/api4/team.go b/api4/team.go
index ed4929326..1e63273e6 100644
--- a/api4/team.go
+++ b/api4/team.go
@@ -46,7 +46,7 @@ func createTeam(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
- rteam, err := app.CreateTeamWithUser(team, c.Session.UserId)
+ rteam, err := app.CreateTeamWithUser(team, c.Session.UserId, c.GetSiteURL())
if err != nil {
c.Err = err
return
diff --git a/api4/user.go b/api4/user.go
index 7b8bfe65e..1668f9c2c 100644
--- a/api4/user.go
+++ b/api4/user.go
@@ -62,7 +62,7 @@ func createUser(c *Context, w http.ResponseWriter, r *http.Request) {
var ruser *model.User
var err *model.AppError
if len(hash) > 0 {
- ruser, err = app.CreateUserWithHash(user, hash, r.URL.Query().Get("d"))
+ ruser, err = app.CreateUserWithHash(user, hash, r.URL.Query().Get("d"), c.GetSiteURL())
} else if len(inviteId) > 0 {
ruser, err = app.CreateUserWithInviteId(user, inviteId, c.GetSiteURL())
} else {
diff --git a/app/apptestlib.go b/app/apptestlib.go
index 41e234130..561c98ed2 100644
--- a/app/apptestlib.go
+++ b/app/apptestlib.go
@@ -161,7 +161,7 @@ func (me *TestHelper) CreatePost(channel *model.Channel) *model.Post {
utils.DisableDebugLogForTest()
var err *model.AppError
- if post, err = CreatePost(post, channel.TeamId, false); err != nil {
+ if post, err = CreatePost(post, channel.TeamId, false, utils.GetSiteURL()); err != nil {
l4g.Error(err.Error())
l4g.Close()
time.Sleep(time.Second)
@@ -174,7 +174,7 @@ func (me *TestHelper) CreatePost(channel *model.Channel) *model.Post {
func LinkUserToTeam(user *model.User, team *model.Team) {
utils.DisableDebugLogForTest()
- err := JoinUserToTeam(team, user)
+ err := JoinUserToTeam(team, user, utils.GetSiteURL())
if err != nil {
l4g.Error(err.Error())
l4g.Close()
diff --git a/app/channel.go b/app/channel.go
index f63592000..af7596ae1 100644
--- a/app/channel.go
+++ b/app/channel.go
@@ -32,7 +32,7 @@ func CreateDefaultChannels(teamId string) ([]*model.Channel, *model.AppError) {
return channels, nil
}
-func JoinDefaultChannels(teamId string, user *model.User, channelRole string) *model.AppError {
+func JoinDefaultChannels(teamId string, user *model.User, channelRole string, siteURL string) *model.AppError {
var err *model.AppError = nil
if result := <-Srv.Store.Channel().GetByName(teamId, "town-square", true); result.Err != nil {
@@ -47,7 +47,7 @@ func JoinDefaultChannels(teamId string, user *model.User, channelRole string) *m
err = cmResult.Err
}
- if err := postJoinChannelMessage(user, townSquare); err != nil {
+ if err := postJoinChannelMessage(user, townSquare, siteURL); err != nil {
l4g.Error(utils.T("api.channel.post_user_add_remove_message_and_forget.error"), err)
}
@@ -66,7 +66,7 @@ func JoinDefaultChannels(teamId string, user *model.User, channelRole string) *m
err = cmResult.Err
}
- if err := postJoinChannelMessage(user, offTopic); err != nil {
+ if err := postJoinChannelMessage(user, offTopic, siteURL); err != nil {
l4g.Error(utils.T("api.channel.post_user_add_remove_message_and_forget.error"), err)
}
@@ -310,7 +310,7 @@ func UpdateChannelMemberNotifyProps(data map[string]string, channelId string, us
}
}
-func DeleteChannel(channel *model.Channel, userId string) *model.AppError {
+func DeleteChannel(channel *model.Channel, userId string, siteURL string) *model.AppError {
uc := Srv.Store.User().Get(userId)
ihc := Srv.Store.Webhook().GetIncomingByChannel(channel.Id)
ohc := Srv.Store.Webhook().GetOutgoingByChannel(channel.Id, -1, -1)
@@ -350,7 +350,7 @@ func DeleteChannel(channel *model.Channel, userId string) *model.AppError {
},
}
- if _, err := CreatePost(post, channel.TeamId, false); err != nil {
+ if _, err := CreatePost(post, channel.TeamId, false, siteURL); err != nil {
l4g.Error(utils.T("api.channel.delete_channel.failed_post.error"), err)
}
@@ -482,7 +482,7 @@ func AddDirectChannels(teamId string, user *model.User) *model.AppError {
return nil
}
-func PostUpdateChannelHeaderMessage(userId string, channelId string, teamId string, oldChannelHeader, newChannelHeader string) *model.AppError {
+func PostUpdateChannelHeaderMessage(userId string, channelId string, teamId string, oldChannelHeader, newChannelHeader string, siteURL string) *model.AppError {
uc := Srv.Store.User().Get(userId)
if uresult := <-uc; uresult.Err != nil {
@@ -511,7 +511,7 @@ func PostUpdateChannelHeaderMessage(userId string, channelId string, teamId stri
},
}
- if _, err := CreatePost(post, teamId, false); err != nil {
+ if _, err := CreatePost(post, teamId, false, siteURL); err != nil {
return model.NewLocAppError("", "api.channel.post_update_channel_header_message_and_forget.post.error", nil, err.Error())
}
}
@@ -519,7 +519,7 @@ func PostUpdateChannelHeaderMessage(userId string, channelId string, teamId stri
return nil
}
-func PostUpdateChannelPurposeMessage(userId string, channelId string, teamId string, oldChannelPurpose string, newChannelPurpose string) *model.AppError {
+func PostUpdateChannelPurposeMessage(userId string, channelId string, teamId string, oldChannelPurpose string, newChannelPurpose string, siteURL string) *model.AppError {
uc := Srv.Store.User().Get(userId)
if uresult := <-uc; uresult.Err != nil {
@@ -547,7 +547,7 @@ func PostUpdateChannelPurposeMessage(userId string, channelId string, teamId str
"new_purpose": newChannelPurpose,
},
}
- if _, err := CreatePost(post, teamId, false); err != nil {
+ if _, err := CreatePost(post, teamId, false, siteURL); err != nil {
return model.NewLocAppError("", "app.channel.post_update_channel_purpose_message.post.error", nil, err.Error())
}
}
@@ -555,7 +555,7 @@ func PostUpdateChannelPurposeMessage(userId string, channelId string, teamId str
return nil
}
-func PostUpdateChannelDisplayNameMessage(userId string, channelId string, teamId string, oldChannelDisplayName, newChannelDisplayName string) *model.AppError {
+func PostUpdateChannelDisplayNameMessage(userId string, channelId string, teamId string, oldChannelDisplayName, newChannelDisplayName string, siteURL string) *model.AppError {
uc := Srv.Store.User().Get(userId)
if uresult := <-uc; uresult.Err != nil {
@@ -577,7 +577,7 @@ func PostUpdateChannelDisplayNameMessage(userId string, channelId string, teamId
},
}
- if _, err := CreatePost(post, teamId, false); err != nil {
+ if _, err := CreatePost(post, teamId, false, siteURL); err != nil {
return model.NewLocAppError("PostUpdateChannelDisplayNameMessage", "api.channel.post_update_channel_displayname_message_and_forget.create_post.error", nil, err.Error())
}
}
@@ -716,10 +716,11 @@ func GetChannelUnread(channelId, userId string) (*model.ChannelUnread, *model.Ap
return channelUnread, nil
}
-func JoinChannel(channel *model.Channel, userId string) *model.AppError {
+func JoinChannel(channel *model.Channel, userId string, siteURL string) *model.AppError {
if channel.DeleteAt > 0 {
return model.NewLocAppError("JoinChannel", "api.channel.join_channel.already_deleted.app_error", nil, "")
}
+
userChan := Srv.Store.User().Get(userId)
memberChan := Srv.Store.Channel().GetMember(channel.Id, userId)
@@ -736,7 +737,7 @@ func JoinChannel(channel *model.Channel, userId string) *model.AppError {
return err
}
- if err := postJoinChannelMessage(user, channel); err != nil {
+ if err := postJoinChannelMessage(user, channel, siteURL); err != nil {
return err
}
} else {
@@ -747,7 +748,7 @@ func JoinChannel(channel *model.Channel, userId string) *model.AppError {
return nil
}
-func postJoinChannelMessage(user *model.User, channel *model.Channel) *model.AppError {
+func postJoinChannelMessage(user *model.User, channel *model.Channel, siteURL string) *model.AppError {
post := &model.Post{
ChannelId: channel.Id,
Message: fmt.Sprintf(utils.T("api.channel.join_channel.post_and_forget"), user.Username),
@@ -758,14 +759,14 @@ func postJoinChannelMessage(user *model.User, channel *model.Channel) *model.App
},
}
- if _, err := CreatePost(post, channel.TeamId, false); err != nil {
+ if _, err := CreatePost(post, channel.TeamId, false, siteURL); err != nil {
return model.NewLocAppError("postJoinChannelMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error())
}
return nil
}
-func LeaveChannel(channelId string, userId string) *model.AppError {
+func LeaveChannel(channelId string, userId string, siteURL string) *model.AppError {
sc := Srv.Store.Channel().Get(channelId, true)
uc := Srv.Store.User().Get(userId)
ccm := Srv.Store.Channel().GetMemberCount(channelId, false)
@@ -797,13 +798,13 @@ func LeaveChannel(channelId string, userId string) *model.AppError {
return err
}
- go postLeaveChannelMessage(user, channel)
+ go postLeaveChannelMessage(user, channel, siteURL)
}
return nil
}
-func postLeaveChannelMessage(user *model.User, channel *model.Channel) *model.AppError {
+func postLeaveChannelMessage(user *model.User, channel *model.Channel, siteURL string) *model.AppError {
post := &model.Post{
ChannelId: channel.Id,
Message: fmt.Sprintf(utils.T("api.channel.leave.left"), user.Username),
@@ -814,14 +815,14 @@ func postLeaveChannelMessage(user *model.User, channel *model.Channel) *model.Ap
},
}
- if _, err := CreatePost(post, channel.TeamId, false); err != nil {
+ if _, err := CreatePost(post, channel.TeamId, false, siteURL); err != nil {
return model.NewLocAppError("postLeaveChannelMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error())
}
return nil
}
-func PostAddToChannelMessage(user *model.User, addedUser *model.User, channel *model.Channel) *model.AppError {
+func PostAddToChannelMessage(user *model.User, addedUser *model.User, channel *model.Channel, siteURL string) *model.AppError {
post := &model.Post{
ChannelId: channel.Id,
Message: fmt.Sprintf(utils.T("api.channel.add_member.added"), addedUser.Username, user.Username),
@@ -833,14 +834,14 @@ func PostAddToChannelMessage(user *model.User, addedUser *model.User, channel *m
},
}
- if _, err := CreatePost(post, channel.TeamId, false); err != nil {
+ if _, err := CreatePost(post, channel.TeamId, false, siteURL); err != nil {
return model.NewLocAppError("postAddToChannelMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error())
}
return nil
}
-func PostRemoveFromChannelMessage(removerUserId string, removedUser *model.User, channel *model.Channel) *model.AppError {
+func PostRemoveFromChannelMessage(removerUserId string, removedUser *model.User, channel *model.Channel, siteURL string) *model.AppError {
post := &model.Post{
ChannelId: channel.Id,
Message: fmt.Sprintf(utils.T("api.channel.remove_member.removed"), removedUser.Username),
@@ -851,7 +852,7 @@ func PostRemoveFromChannelMessage(removerUserId string, removedUser *model.User,
},
}
- if _, err := CreatePost(post, channel.TeamId, false); err != nil {
+ if _, err := CreatePost(post, channel.TeamId, false, siteURL); err != nil {
return model.NewLocAppError("postRemoveFromChannelMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error())
}
@@ -890,7 +891,7 @@ func removeUserFromChannel(userIdToRemove string, removerUserId string, channel
return nil
}
-func RemoveUserFromChannel(userIdToRemove string, removerUserId string, channel *model.Channel) *model.AppError {
+func RemoveUserFromChannel(userIdToRemove string, removerUserId string, channel *model.Channel, siteURL string) *model.AppError {
var err *model.AppError
if err = removeUserFromChannel(userIdToRemove, removerUserId, channel); err != nil {
return err
@@ -901,7 +902,7 @@ func RemoveUserFromChannel(userIdToRemove string, removerUserId string, channel
return err
}
- go PostRemoveFromChannelMessage(removerUserId, user, channel)
+ go PostRemoveFromChannelMessage(removerUserId, user, channel, siteURL)
return nil
}
diff --git a/app/command.go b/app/command.go
index 491813efe..4583cf81b 100644
--- a/app/command.go
+++ b/app/command.go
@@ -38,7 +38,7 @@ func GetCommandProvider(name string) CommandProvider {
return nil
}
-func CreateCommandPost(post *model.Post, teamId string, response *model.CommandResponse) (*model.Post, *model.AppError) {
+func CreateCommandPost(post *model.Post, teamId string, response *model.CommandResponse, siteURL string) (*model.Post, *model.AppError) {
post.Message = parseSlackLinksToMarkdown(response.Text)
post.CreateAt = model.GetMillis()
@@ -48,7 +48,7 @@ func CreateCommandPost(post *model.Post, teamId string, response *model.CommandR
switch response.ResponseType {
case model.COMMAND_RESPONSE_TYPE_IN_CHANNEL:
- return CreatePost(post, teamId, true)
+ return CreatePost(post, teamId, true, siteURL)
case model.COMMAND_RESPONSE_TYPE_EPHEMERAL:
if response.Text == "" {
return post, nil
@@ -237,7 +237,7 @@ func HandleCommandResponse(command *model.Command, args *model.CommandArgs, resp
}
}
- if _, err := CreateCommandPost(post, args.TeamId, response); err != nil {
+ if _, err := CreateCommandPost(post, args.TeamId, response, args.SiteURL); err != nil {
l4g.Error(err.Error())
}
diff --git a/app/command_echo.go b/app/command_echo.go
index 40d70e54a..3bfe67cd7 100644
--- a/app/command_echo.go
+++ b/app/command_echo.go
@@ -88,7 +88,7 @@ func (me *EchoProvider) DoCommand(args *model.CommandArgs, message string) *mode
time.Sleep(time.Duration(delay) * time.Second)
- if _, err := CreatePost(post, args.TeamId, true); err != nil {
+ if _, err := CreatePost(post, args.TeamId, true, args.SiteURL); err != nil {
l4g.Error(args.T("api.command_echo.create.app_error"), err)
}
}()
diff --git a/app/command_join.go b/app/command_join.go
index 5b19dd7a0..e7d25aa16 100644
--- a/app/command_join.go
+++ b/app/command_join.go
@@ -45,7 +45,7 @@ func (me *JoinProvider) DoCommand(args *model.CommandArgs, message string) *mode
return &model.CommandResponse{Text: args.T("api.command_join.fail.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
}
- if err := JoinChannel(channel, args.UserId); err != nil {
+ if err := JoinChannel(channel, args.UserId, args.SiteURL); err != nil {
return &model.CommandResponse{Text: args.T("api.command_join.fail.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
}
diff --git a/app/command_loadtest.go b/app/command_loadtest.go
index d3c7474ae..b1d89826b 100644
--- a/app/command_loadtest.go
+++ b/app/command_loadtest.go
@@ -357,7 +357,7 @@ func (me *LoadTestProvider) UrlCommand(args *model.CommandArgs, message string)
post.ChannelId = args.ChannelId
post.UserId = args.UserId
- if _, err := CreatePost(post, args.TeamId, false); err != nil {
+ if _, err := CreatePost(post, args.TeamId, false, args.SiteURL); err != nil {
return &model.CommandResponse{Text: "Unable to create post", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
}
}
@@ -396,7 +396,7 @@ func (me *LoadTestProvider) JsonCommand(args *model.CommandArgs, message string)
post.Message = message
}
- if _, err := CreatePost(post, args.TeamId, false); err != nil {
+ if _, err := CreatePost(post, args.TeamId, false, args.SiteURL); err != nil {
return &model.CommandResponse{Text: "Unable to create post", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
}
return &model.CommandResponse{Text: "Loaded data", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
diff --git a/app/command_msg.go b/app/command_msg.go
index fd4ace61a..06b17fdc4 100644
--- a/app/command_msg.go
+++ b/app/command_msg.go
@@ -89,7 +89,7 @@ func (me *msgProvider) DoCommand(args *model.CommandArgs, message string) *model
post.Message = parsedMessage
post.ChannelId = targetChannelId
post.UserId = args.UserId
- if _, err := CreatePost(post, args.TeamId, true); err != nil {
+ if _, err := CreatePost(post, args.TeamId, true, args.SiteURL); err != nil {
return &model.CommandResponse{Text: args.T("api.command_msg.fail.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
}
}
diff --git a/app/import.go b/app/import.go
index 1ca532902..a5ed69843 100644
--- a/app/import.go
+++ b/app/import.go
@@ -865,7 +865,7 @@ func OldImportUser(team *model.Team, user *model.User) *model.User {
l4g.Error(utils.T("api.import.import_user.set_email.error"), cresult.Err)
}
- if err := JoinUserToTeam(team, user); err != nil {
+ if err := JoinUserToTeam(team, user, utils.GetSiteURL()); err != nil {
l4g.Error(utils.T("api.import.import_user.join_team.error"), err)
}
@@ -915,37 +915,8 @@ func OldImportIncomingWebhookPost(post *model.Post, props model.StringInterface)
if len(props) > 0 {
for key, val := range props {
if key == "attachments" {
- if list, success := val.([]interface{}); success {
- // parse attachment links into Markdown format
- for i, aInt := range list {
- attachment := aInt.(map[string]interface{})
- if aText, ok := attachment["text"].(string); ok {
- aText = linkWithTextRegex.ReplaceAllString(aText, "[${2}](${1})")
- attachment["text"] = aText
- list[i] = attachment
- }
- if aText, ok := attachment["pretext"].(string); ok {
- 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 fValue, ok := field["value"].(string); ok {
- fValue = linkWithTextRegex.ReplaceAllString(fValue, "[${2}](${1})")
- field["value"] = fValue
- fields[j] = field
- }
- }
- attachment["fields"] = fields
- list[i] = attachment
- }
- }
- }
- post.AddProp(key, list)
+ if attachments, success := val.([]*model.SlackAttachment); success {
+ parseSlackAttachment(post, attachments)
}
} else if key != "from_webhook" {
post.AddProp(key, val)
diff --git a/app/notification.go b/app/notification.go
index 469d114ee..7b61de9ac 100644
--- a/app/notification.go
+++ b/app/notification.go
@@ -24,7 +24,7 @@ import (
"github.com/nicksnyder/go-i18n/i18n"
)
-func SendNotifications(post *model.Post, team *model.Team, channel *model.Channel, sender *model.User) ([]string, *model.AppError) {
+func SendNotifications(post *model.Post, team *model.Team, channel *model.Channel, sender *model.User, siteURL string) ([]string, *model.AppError) {
pchan := Srv.Store.User().GetAllProfilesInChannel(channel.Id, true)
cmnchan := Srv.Store.Channel().GetAllChannelMembersNotifyPropsForChannel(channel.Id, true)
var fchan store.StoreChannel
@@ -171,7 +171,7 @@ func SendNotifications(post *model.Post, team *model.Team, channel *model.Channe
}
if userAllowsEmails && status.Status != model.STATUS_ONLINE && profileMap[id].DeleteAt == 0 {
- sendNotificationEmail(post, profileMap[id], channel, team, senderName, sender)
+ sendNotificationEmail(post, profileMap[id], channel, team, senderName, sender, siteURL)
}
}
}
@@ -286,7 +286,7 @@ func SendNotifications(post *model.Post, team *model.Team, channel *model.Channe
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_POSTED, "", post.ChannelId, "", nil)
message.Add("post", post.ToJson())
message.Add("channel_type", channel.Type)
- message.Add("channel_display_name", channel.DisplayName)
+ message.Add("channel_display_name", channelName)
message.Add("channel_name", channel.Name)
message.Add("sender_name", senderUsername)
message.Add("team_id", team.Id)
@@ -317,9 +317,8 @@ func SendNotifications(post *model.Post, team *model.Team, channel *model.Channe
return mentionedUsersList, nil
}
-func sendNotificationEmail(post *model.Post, user *model.User, channel *model.Channel, team *model.Team, senderName string, sender *model.User) *model.AppError {
- if channel.IsGroupOrDirect() && channel.TeamId != team.Id {
- // this message is a cross-team DM/GM so we need to find a team that the recipient is on to use in the link
+func sendNotificationEmail(post *model.Post, user *model.User, channel *model.Channel, team *model.Team, senderName string, sender *model.User, siteURL string) *model.AppError {
+ if channel.IsGroupOrDirect() {
if result := <-Srv.Store.Team().GetTeamsByUserId(user.Id); result.Err != nil {
return result.Err
} else {
@@ -368,7 +367,7 @@ func sendNotificationEmail(post *model.Post, user *model.User, channel *model.Ch
var mailTemplate string
var mailParameters map[string]interface{}
- teamURL := utils.GetSiteURL() + "/" + team.Name
+ teamURL := siteURL + "/" + team.Name
tm := time.Unix(post.CreateAt/1000, 0)
userLocale := utils.GetUserTranslations(user.Locale)
@@ -406,7 +405,7 @@ func sendNotificationEmail(post *model.Post, user *model.User, channel *model.Ch
subject := fmt.Sprintf("[%v] %v", utils.Cfg.TeamSettings.SiteName, userLocale(mailTemplate, mailParameters))
bodyPage := utils.NewHTMLTemplate("post_body", user.Locale)
- bodyPage.Props["SiteURL"] = utils.GetSiteURL()
+ bodyPage.Props["SiteURL"] = siteURL
bodyPage.Props["PostMessage"] = GetMessageForNotification(post, userLocale)
if team.Name != "select_team" {
bodyPage.Props["TeamLink"] = teamURL + "/pl/" + post.Id
diff --git a/app/notification_test.go b/app/notification_test.go
index 3768a95c7..fd8c4bf57 100644
--- a/app/notification_test.go
+++ b/app/notification_test.go
@@ -7,6 +7,7 @@ import (
"testing"
"github.com/mattermost/platform/model"
+ "github.com/mattermost/platform/utils"
)
func TestSendNotifications(t *testing.T) {
@@ -18,13 +19,13 @@ func TestSendNotifications(t *testing.T) {
UserId: th.BasicUser.Id,
ChannelId: th.BasicChannel.Id,
Message: "@" + th.BasicUser2.Username,
- }, th.BasicTeam.Id, true)
+ }, th.BasicTeam.Id, true, utils.GetSiteURL())
if postErr != nil {
t.Fatal(postErr)
}
- mentions, err := SendNotifications(post1, th.BasicTeam, th.BasicChannel, th.BasicUser)
+ mentions, err := SendNotifications(post1, th.BasicTeam, th.BasicChannel, th.BasicUser, utils.GetSiteURL())
if err != nil {
t.Fatal(err)
} else if mentions == nil {
diff --git a/app/post.go b/app/post.go
index a41da6c90..c4d128399 100644
--- a/app/post.go
+++ b/app/post.go
@@ -24,7 +24,7 @@ var (
linkWithTextRegex = regexp.MustCompile(`<([^<\|]+)\|([^>]+)>`)
)
-func CreatePostAsUser(post *model.Post) (*model.Post, *model.AppError) {
+func CreatePostAsUser(post *model.Post, siteURL string) (*model.Post, *model.AppError) {
// Check that channel has not been deleted
var channel *model.Channel
if result := <-Srv.Store.Channel().Get(post.ChannelId, true); result.Err != nil {
@@ -41,7 +41,7 @@ func CreatePostAsUser(post *model.Post) (*model.Post, *model.AppError) {
return nil, err
}
- if rp, err := CreatePost(post, channel.TeamId, true); err != nil {
+ if rp, err := CreatePost(post, channel.TeamId, true, siteURL); err != nil {
if err.Id == "api.post.create_post.root_id.app_error" ||
err.Id == "api.post.create_post.channel_root_id.app_error" ||
err.Id == "api.post.create_post.parent_id.app_error" {
@@ -62,7 +62,7 @@ func CreatePostAsUser(post *model.Post) (*model.Post, *model.AppError) {
}
-func CreatePost(post *model.Post, teamId string, triggerWebhooks bool) (*model.Post, *model.AppError) {
+func CreatePost(post *model.Post, teamId string, triggerWebhooks bool, siteURL string) (*model.Post, *model.AppError) {
var pchan store.StoreChannel
if len(post.RootId) > 0 {
pchan = Srv.Store.Post().Get(post.RootId)
@@ -119,14 +119,14 @@ func CreatePost(post *model.Post, teamId string, triggerWebhooks bool) (*model.P
}
}
- if err := handlePostEvents(rpost, teamId, triggerWebhooks); err != nil {
+ if err := handlePostEvents(rpost, teamId, triggerWebhooks, siteURL); err != nil {
return nil, err
}
return rpost, nil
}
-func handlePostEvents(post *model.Post, teamId string, triggerWebhooks bool) *model.AppError {
+func handlePostEvents(post *model.Post, teamId string, triggerWebhooks bool, siteURL string) *model.AppError {
var tchan store.StoreChannel
if len(teamId) > 0 {
tchan = Srv.Store.Team().Get(teamId)
@@ -163,13 +163,13 @@ func handlePostEvents(post *model.Post, teamId string, triggerWebhooks bool) *mo
user = result.Data.(*model.User)
}
- if _, err := SendNotifications(post, team, channel, user); err != nil {
+ if _, err := SendNotifications(post, team, channel, user, siteURL); err != nil {
return err
}
if triggerWebhooks {
go func() {
- if err := handleWebhookEvents(post, team, channel, user); err != nil {
+ if err := handleWebhookEvents(post, team, channel, user, siteURL); err != nil {
l4g.Error(err.Error())
}
}()
@@ -180,40 +180,20 @@ func handlePostEvents(post *model.Post, teamId string, triggerWebhooks bool) *mo
// This method only parses and processes the attachments,
// all else should be set in the post which is passed
-func parseSlackAttachment(post *model.Post, attachments interface{}) {
+func parseSlackAttachment(post *model.Post, attachments []*model.SlackAttachment) {
post.Type = model.POST_SLACK_ATTACHMENT
- if list, success := attachments.([]interface{}); success {
- for i, aInt := range list {
- attachment := aInt.(map[string]interface{})
- if aText, ok := attachment["text"].(string); ok {
- aText = linkWithTextRegex.ReplaceAllString(aText, "[${2}](${1})")
- attachment["text"] = aText
- list[i] = attachment
- }
- if aText, ok := attachment["pretext"].(string); ok {
- 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 fValue, ok := field["value"].(string); ok {
- fValue = linkWithTextRegex.ReplaceAllString(fValue, "[${2}](${1})")
- field["value"] = fValue
- fields[j] = field
- }
- }
- attachment["fields"] = fields
- list[i] = attachment
- }
+ for _, attachment := range attachments {
+ attachment.Text = parseSlackLinksToMarkdown(attachment.Text)
+ attachment.Pretext = parseSlackLinksToMarkdown(attachment.Pretext)
+
+ for _, field := range attachment.Fields {
+ if value, ok := field.Value.(string); ok {
+ field.Value = parseSlackLinksToMarkdown(value)
}
}
- post.AddProp("attachments", list)
}
+ post.AddProp("attachments", attachments)
}
func parseSlackLinksToMarkdown(text string) string {
@@ -365,7 +345,7 @@ func GetFlaggedPosts(userId string, offset int, limit int) (*model.PostList, *mo
}
}
-func GetPermalinkPost(postId string, userId string) (*model.PostList, *model.AppError) {
+func GetPermalinkPost(postId string, userId string, siteURL string) (*model.PostList, *model.AppError) {
if result := <-Srv.Store.Post().Get(postId); result.Err != nil {
return nil, result.Err
} else {
@@ -382,7 +362,7 @@ func GetPermalinkPost(postId string, userId string) (*model.PostList, *model.App
return nil, err
}
- if err = JoinChannel(channel, userId); err != nil {
+ if err = JoinChannel(channel, userId, siteURL); err != nil {
return nil, err
}
diff --git a/app/slackimport.go b/app/slackimport.go
index 5512d8c00..fcdd765bb 100644
--- a/app/slackimport.go
+++ b/app/slackimport.go
@@ -40,17 +40,17 @@ type SlackFile struct {
}
type SlackPost struct {
- User string `json:"user"`
- BotId string `json:"bot_id"`
- BotUsername string `json:"username"`
- Text string `json:"text"`
- TimeStamp string `json:"ts"`
- Type string `json:"type"`
- SubType string `json:"subtype"`
- Comment *SlackComment `json:"comment"`
- Upload bool `json:"upload"`
- File *SlackFile `json:"file"`
- Attachments []SlackAttachment `json:"attachments"`
+ User string `json:"user"`
+ BotId string `json:"bot_id"`
+ BotUsername string `json:"username"`
+ Text string `json:"text"`
+ TimeStamp string `json:"ts"`
+ Type string `json:"type"`
+ SubType string `json:"subtype"`
+ Comment *SlackComment `json:"comment"`
+ Upload bool `json:"upload"`
+ File *SlackFile `json:"file"`
+ Attachments []*model.SlackAttachment `json:"attachments"`
}
type SlackComment struct {
@@ -58,13 +58,6 @@ type SlackComment struct {
Comment string `json:"comment"`
}
-type SlackAttachment struct {
- Id int `json:"id"`
- Text string `json:"text"`
- Pretext string `json:"pretext"`
- Fields []map[string]interface{} `json:"fields"`
-}
-
func truncateRunes(s string, i int) string {
runes := []rune(s)
if len(runes) > i {
@@ -167,7 +160,7 @@ func SlackAddUsers(teamId string, slackusers []SlackUser, log *bytes.Buffer) map
if result := <-Srv.Store.User().GetByEmail(email); result.Err == nil {
existingUser := result.Data.(*model.User)
addedUsers[sUser.Id] = existingUser
- if err := JoinUserToTeam(team, addedUsers[sUser.Id]); err != nil {
+ if err := JoinUserToTeam(team, addedUsers[sUser.Id], utils.GetSiteURL()); err != nil {
log.WriteString(utils.T("api.slackimport.slack_add_users.merge_existing_failed", map[string]interface{}{"Email": existingUser.Email, "Username": existingUser.Username}))
} else {
log.WriteString(utils.T("api.slackimport.slack_add_users.merge_existing", map[string]interface{}{"Email": existingUser.Email, "Username": existingUser.Username}))
@@ -284,15 +277,7 @@ func SlackAddPosts(teamId string, channel *model.Channel, posts []SlackPost, use
props := make(model.StringInterface)
props["override_username"] = sPost.BotUsername
if len(sPost.Attachments) > 0 {
- var mAttachments []interface{}
- for _, attachment := range sPost.Attachments {
- mAttachments = append(mAttachments, map[string]interface{}{
- "text": attachment.Text,
- "pretext": attachment.Pretext,
- "fields": attachment.Fields,
- })
- }
- props["attachments"] = mAttachments
+ props["attachments"] = sPost.Attachments
}
post := &model.Post{
diff --git a/app/team.go b/app/team.go
index 6bc4d258e..d0d907731 100644
--- a/app/team.go
+++ b/app/team.go
@@ -29,7 +29,7 @@ func CreateTeam(team *model.Team) (*model.Team, *model.AppError) {
}
}
-func CreateTeamWithUser(team *model.Team, userId string) (*model.Team, *model.AppError) {
+func CreateTeamWithUser(team *model.Team, userId string, siteURL string) (*model.Team, *model.AppError) {
var user *model.User
var err *model.AppError
if user, err = GetUser(userId); err != nil {
@@ -47,7 +47,7 @@ func CreateTeamWithUser(team *model.Team, userId string) (*model.Team, *model.Ap
return nil, err
}
- if err = JoinUserToTeam(rteam, user); err != nil {
+ if err = JoinUserToTeam(rteam, user, siteURL); err != nil {
return nil, err
}
@@ -137,7 +137,7 @@ func UpdateTeamMemberRoles(teamId string, userId string, newRoles string) (*mode
return member, nil
}
-func AddUserToTeam(teamId string, userId string) (*model.Team, *model.AppError) {
+func AddUserToTeam(teamId string, userId string, siteURL string) (*model.Team, *model.AppError) {
tchan := Srv.Store.Team().Get(teamId)
uchan := Srv.Store.User().Get(userId)
@@ -155,22 +155,22 @@ func AddUserToTeam(teamId string, userId string) (*model.Team, *model.AppError)
user = result.Data.(*model.User)
}
- if err := JoinUserToTeam(team, user); err != nil {
+ if err := JoinUserToTeam(team, user, siteURL); err != nil {
return nil, err
}
return team, nil
}
-func AddUserToTeamByTeamId(teamId string, user *model.User) *model.AppError {
+func AddUserToTeamByTeamId(teamId string, user *model.User, siteURL string) *model.AppError {
if result := <-Srv.Store.Team().Get(teamId); result.Err != nil {
return result.Err
} else {
- return JoinUserToTeam(result.Data.(*model.Team), user)
+ return JoinUserToTeam(result.Data.(*model.Team), user, siteURL)
}
}
-func AddUserToTeamByHash(userId string, hash string, data string) (*model.Team, *model.AppError) {
+func AddUserToTeamByHash(userId string, hash string, data string, siteURL string) (*model.Team, *model.AppError) {
props := model.MapFromJson(strings.NewReader(data))
if !model.ComparePassword(hash, fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt)) {
@@ -199,14 +199,14 @@ func AddUserToTeamByHash(userId string, hash string, data string) (*model.Team,
user = result.Data.(*model.User)
}
- if err := JoinUserToTeam(team, user); err != nil {
+ if err := JoinUserToTeam(team, user, siteURL); err != nil {
return nil, err
}
return team, nil
}
-func AddUserToTeamByInviteId(inviteId string, userId string) (*model.Team, *model.AppError) {
+func AddUserToTeamByInviteId(inviteId string, userId string, siteURL string) (*model.Team, *model.AppError) {
tchan := Srv.Store.Team().GetByInviteId(inviteId)
uchan := Srv.Store.User().Get(userId)
@@ -224,7 +224,7 @@ func AddUserToTeamByInviteId(inviteId string, userId string) (*model.Team, *mode
user = result.Data.(*model.User)
}
- if err := JoinUserToTeam(team, user); err != nil {
+ if err := JoinUserToTeam(team, user, siteURL); err != nil {
return nil, err
}
@@ -269,7 +269,7 @@ func joinUserToTeam(team *model.Team, user *model.User) (bool, *model.AppError)
return false, nil
}
-func JoinUserToTeam(team *model.Team, user *model.User) *model.AppError {
+func JoinUserToTeam(team *model.Team, user *model.User, siteURL string) *model.AppError {
if alreadyAdded, err := joinUserToTeam(team, user); err != nil {
return err
@@ -284,7 +284,7 @@ func JoinUserToTeam(team *model.Team, user *model.User) *model.AppError {
}
// Soft error if there is an issue joining the default channels
- if err := JoinDefaultChannels(team.Id, user, channelRole); err != nil {
+ if err := JoinDefaultChannels(team.Id, user, channelRole, siteURL); err != nil {
l4g.Error(utils.T("api.user.create_user.joining.error"), user.Id, team.Id, err)
}
diff --git a/app/team_test.go b/app/team_test.go
index 64af0c4af..75f09f1ca 100644
--- a/app/team_test.go
+++ b/app/team_test.go
@@ -8,6 +8,7 @@ import (
"testing"
"github.com/mattermost/platform/model"
+ "github.com/mattermost/platform/utils"
)
func TestCreateTeam(t *testing.T) {
@@ -42,12 +43,12 @@ func TestCreateTeamWithUser(t *testing.T) {
Type: model.TEAM_OPEN,
}
- if _, err := CreateTeamWithUser(team, th.BasicUser.Id); err != nil {
+ if _, err := CreateTeamWithUser(team, th.BasicUser.Id, utils.GetSiteURL()); err != nil {
t.Log(err)
t.Fatal("Should create a new team with existing user")
}
- if _, err := CreateTeamWithUser(team, model.NewId()); err == nil {
+ if _, err := CreateTeamWithUser(team, model.NewId(), utils.GetSiteURL()); err == nil {
t.Fatal("Should not create a new team - user does not exist")
}
@@ -63,7 +64,7 @@ func TestCreateTeamWithUser(t *testing.T) {
}
//Fail to create a team with user when user has set email without domain
- if _, err := CreateTeamWithUser(team2, ruser.Id); err == nil {
+ if _, err := CreateTeamWithUser(team2, ruser.Id, utils.GetSiteURL()); err == nil {
t.Log(err.Message)
t.Fatal("Should not create a team with user when user has set email without domain")
} else {
@@ -95,7 +96,7 @@ func TestAddUserToTeam(t *testing.T) {
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
ruser, _ := CreateUser(&user)
- if _, err := AddUserToTeam(th.BasicTeam.Id, ruser.Id); err != nil {
+ if _, err := AddUserToTeam(th.BasicTeam.Id, ruser.Id, utils.GetSiteURL()); err != nil {
t.Log(err)
t.Fatal("Should add user to the team")
}
@@ -107,7 +108,7 @@ func TestAddUserToTeamByTeamId(t *testing.T) {
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
ruser, _ := CreateUser(&user)
- if err := AddUserToTeamByTeamId(th.BasicTeam.Id, ruser); err != nil {
+ if err := AddUserToTeamByTeamId(th.BasicTeam.Id, ruser, utils.GetSiteURL()); err != nil {
t.Log(err)
t.Fatal("Should add user to the team")
}
diff --git a/app/user.go b/app/user.go
index c872a7fa1..c877640d6 100644
--- a/app/user.go
+++ b/app/user.go
@@ -29,7 +29,7 @@ import (
"github.com/mattermost/platform/utils"
)
-func CreateUserWithHash(user *model.User, hash string, data string) (*model.User, *model.AppError) {
+func CreateUserWithHash(user *model.User, hash string, data string, siteURL string) (*model.User, *model.AppError) {
if err := IsUserSignUpAllowed(); err != nil {
return nil, err
}
@@ -62,7 +62,7 @@ func CreateUserWithHash(user *model.User, hash string, data string) (*model.User
return nil, err
}
- if err := JoinUserToTeam(team, ruser); err != nil {
+ if err := JoinUserToTeam(team, ruser, siteURL); err != nil {
return nil, err
}
@@ -91,7 +91,7 @@ func CreateUserWithInviteId(user *model.User, inviteId string, siteURL string) (
return nil, err
}
- if err := JoinUserToTeam(team, ruser); err != nil {
+ if err := JoinUserToTeam(team, ruser, siteURL); err != nil {
return nil, err
}
@@ -216,7 +216,7 @@ func createUser(user *model.User) (*model.User, *model.AppError) {
}
}
-func CreateOAuthUser(service string, userData io.Reader, teamId string) (*model.User, *model.AppError) {
+func CreateOAuthUser(service string, userData io.Reader, teamId string, siteURL string) (*model.User, *model.AppError) {
if !utils.Cfg.TeamSettings.EnableUserCreation {
return nil, model.NewAppError("CreateOAuthUser", "api.user.create_user.disabled.app_error", nil, "", http.StatusNotImplemented)
}
@@ -268,7 +268,7 @@ func CreateOAuthUser(service string, userData io.Reader, teamId string) (*model.
}
if len(teamId) > 0 {
- err = AddUserToTeamByTeamId(teamId, user)
+ err = AddUserToTeamByTeamId(teamId, user, siteURL)
if err != nil {
return nil, err
}
diff --git a/app/user_test.go b/app/user_test.go
index ec0e2b73c..d8d6bdc79 100644
--- a/app/user_test.go
+++ b/app/user_test.go
@@ -70,7 +70,7 @@ func TestCreateOAuthUser(t *testing.T) {
glUser := oauthgitlab.GitLabUser{Id: int64(r.Intn(1000)), Username: "joram" + model.NewId(), Email: model.NewId() + "@simulator.amazonses.com", Name: "Joram Wilander"}
json := glUser.ToJson()
- user, err := CreateOAuthUser(model.USER_AUTH_SERVICE_GITLAB, strings.NewReader(json), th.BasicTeam.Id)
+ user, err := CreateOAuthUser(model.USER_AUTH_SERVICE_GITLAB, strings.NewReader(json), th.BasicTeam.Id, utils.GetSiteURL())
if err != nil {
t.Fatal(err)
}
@@ -87,7 +87,7 @@ func TestCreateOAuthUser(t *testing.T) {
}()
utils.Cfg.TeamSettings.EnableUserCreation = false
- _, err = CreateOAuthUser(model.USER_AUTH_SERVICE_GITLAB, strings.NewReader(json), th.BasicTeam.Id)
+ _, err = CreateOAuthUser(model.USER_AUTH_SERVICE_GITLAB, strings.NewReader(json), th.BasicTeam.Id, utils.GetSiteURL())
if err == nil {
t.Fatal("should have failed - user creation disabled")
}
@@ -253,7 +253,7 @@ func createGitlabUser(t *testing.T, email string, username string) (*model.User,
var user *model.User
var err *model.AppError
- if user, err = CreateOAuthUser("gitlab", bytes.NewReader(gitlabUser), ""); err != nil {
+ if user, err = CreateOAuthUser("gitlab", bytes.NewReader(gitlabUser), "", utils.GetSiteURL()); err != nil {
t.Fatal("unable to create the user")
}
diff --git a/app/webhook.go b/app/webhook.go
index 55a073c75..c3853b97b 100644
--- a/app/webhook.go
+++ b/app/webhook.go
@@ -24,7 +24,7 @@ const (
TRIGGERWORDS_STARTSWITH = 1
)
-func handleWebhookEvents(post *model.Post, team *model.Team, channel *model.Channel, user *model.User) *model.AppError {
+func handleWebhookEvents(post *model.Post, team *model.Team, channel *model.Channel, user *model.User, siteURL string) *model.AppError {
if !utils.Cfg.ServiceSettings.EnableOutgoingWebhooks {
return nil
}
@@ -107,7 +107,7 @@ func handleWebhookEvents(post *model.Post, team *model.Team, channel *model.Chan
respProps := model.MapFromJson(resp.Body)
if text, ok := respProps["text"]; ok {
- if _, err := CreateWebhookPost(hook.CreatorId, hook.TeamId, post.ChannelId, text, respProps["username"], respProps["icon_url"], post.Props, post.Type); err != nil {
+ if _, err := CreateWebhookPost(hook.CreatorId, hook.TeamId, post.ChannelId, text, respProps["username"], respProps["icon_url"], post.Props, post.Type, siteURL); err != nil {
l4g.Error(utils.T("api.post.handle_webhook_events_and_forget.create_post.error"), err)
}
}
@@ -121,7 +121,7 @@ func handleWebhookEvents(post *model.Post, team *model.Team, channel *model.Chan
return nil
}
-func CreateWebhookPost(userId, teamId, channelId, text, overrideUsername, overrideIconUrl string, props model.StringInterface, postType string) (*model.Post, *model.AppError) {
+func CreateWebhookPost(userId, teamId, channelId, text, overrideUsername, overrideIconUrl string, props model.StringInterface, postType string, siteURL string) (*model.Post, *model.AppError) {
// parse links into Markdown format
linkWithTextRegex := regexp.MustCompile(`<([^<\|]+)\|([^>]+)>`)
text = linkWithTextRegex.ReplaceAllString(text, "[${2}](${1})")
@@ -150,37 +150,8 @@ func CreateWebhookPost(userId, teamId, channelId, text, overrideUsername, overri
if len(props) > 0 {
for key, val := range props {
if key == "attachments" {
- if list, success := val.([]interface{}); success {
- // parse attachment links into Markdown format
- for i, aInt := range list {
- attachment := aInt.(map[string]interface{})
- if aText, ok := attachment["text"].(string); ok {
- aText = linkWithTextRegex.ReplaceAllString(aText, "[${2}](${1})")
- attachment["text"] = aText
- list[i] = attachment
- }
- if aText, ok := attachment["pretext"].(string); ok {
- 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 fValue, ok := field["value"].(string); ok {
- fValue = linkWithTextRegex.ReplaceAllString(fValue, "[${2}](${1})")
- field["value"] = fValue
- fields[j] = field
- }
- }
- attachment["fields"] = fields
- list[i] = attachment
- }
- }
- }
- post.AddProp(key, list)
+ if attachments, success := val.([]*model.SlackAttachment); success {
+ parseSlackAttachment(post, attachments)
}
} else if key != "override_icon_url" && key != "override_username" && key != "from_webhook" {
post.AddProp(key, val)
@@ -188,7 +159,7 @@ func CreateWebhookPost(userId, teamId, channelId, text, overrideUsername, overri
}
}
- if _, err := CreatePost(post, teamId, false); err != nil {
+ if _, err := CreatePost(post, teamId, false, siteURL); err != nil {
return nil, model.NewLocAppError("CreateWebhookPost", "api.post.create_webhook_post.creating.app_error", nil, "err="+err.Message)
}
@@ -452,7 +423,7 @@ func RegenOutgoingWebhookToken(hook *model.OutgoingWebhook) (*model.OutgoingWebh
}
}
-func HandleIncomingWebhook(hookId string, req *model.IncomingWebhookRequest) *model.AppError {
+func HandleIncomingWebhook(hookId string, req *model.IncomingWebhookRequest, siteURL string) *model.AppError {
if !utils.Cfg.ServiceSettings.EnableIncomingWebhooks {
return model.NewAppError("HandleIncomingWebhook", "web.incoming_webhook.disabled.app_error", nil, "", http.StatusNotImplemented)
}
@@ -477,7 +448,7 @@ func HandleIncomingWebhook(hookId string, req *model.IncomingWebhookRequest) *mo
webhookType := req.Type
// attachments is in here for slack compatibility
- if req.Attachments != nil {
+ if len(req.Attachments) > 0 {
if len(req.Props) == 0 {
req.Props = make(model.StringInterface)
}
@@ -543,7 +514,7 @@ func HandleIncomingWebhook(hookId string, req *model.IncomingWebhookRequest) *mo
return model.NewAppError("HandleIncomingWebhook", "web.incoming_webhook.permissions.app_error", nil, "", http.StatusForbidden)
}
- if _, err := CreateWebhookPost(hook.UserId, hook.TeamId, channel.Id, text, overrideUsername, overrideIconUrl, req.Props, webhookType); err != nil {
+ if _, err := CreateWebhookPost(hook.UserId, hook.TeamId, channel.Id, text, overrideUsername, overrideIconUrl, req.Props, webhookType, siteURL); err != nil {
return err
}
diff --git a/cmd/platform/channel.go b/cmd/platform/channel.go
index b99486242..2510f90f3 100644
--- a/cmd/platform/channel.go
+++ b/cmd/platform/channel.go
@@ -168,7 +168,7 @@ func removeUserFromChannel(channel *model.Channel, user *model.User, userArg str
CommandPrintErrorln("Can't find user '" + userArg + "'")
return
}
- if err := app.RemoveUserFromChannel(user.Id, "", channel); err != nil {
+ if err := app.RemoveUserFromChannel(user.Id, "", channel, utils.GetSiteURL()); err != nil {
CommandPrintErrorln("Unable to remove '" + userArg + "' from " + channel.Name + ". Error: " + err.Error())
}
}
diff --git a/cmd/platform/oldcommands.go b/cmd/platform/oldcommands.go
index 518dcbaaf..18758cc61 100644
--- a/cmd/platform/oldcommands.go
+++ b/cmd/platform/oldcommands.go
@@ -274,7 +274,7 @@ func cmdCreateUser() {
}
if team != nil {
- err = app.JoinUserToTeam(team, ruser)
+ err = app.JoinUserToTeam(team, ruser, utils.GetSiteURL())
if err != nil {
l4g.Error("%v", err)
flushLogAndExit(1)
@@ -546,7 +546,7 @@ func cmdLeaveChannel() {
channel = result.Data.(*model.Channel)
}
- err := app.RemoveUserFromChannel(user.Id, user.Id, channel)
+ err := app.RemoveUserFromChannel(user.Id, user.Id, channel, utils.GetSiteURL())
if err != nil {
l4g.Error("%v", err)
flushLogAndExit(1)
@@ -673,7 +673,7 @@ func cmdJoinTeam() {
user = result.Data.(*model.User)
}
- err := app.JoinUserToTeam(team, user)
+ err := app.JoinUserToTeam(team, user, utils.GetSiteURL())
if err != nil {
l4g.Error("%v", err)
flushLogAndExit(1)
diff --git a/cmd/platform/team.go b/cmd/platform/team.go
index 1dc5d46eb..6dab2ad16 100644
--- a/cmd/platform/team.go
+++ b/cmd/platform/team.go
@@ -8,6 +8,7 @@ import (
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
+ "github.com/mattermost/platform/utils"
"github.com/spf13/cobra"
)
@@ -154,7 +155,7 @@ func addUserToTeam(team *model.Team, user *model.User, userArg string) {
CommandPrintErrorln("Can't find user '" + userArg + "'")
return
}
- if err := app.JoinUserToTeam(team, user); err != nil {
+ if err := app.JoinUserToTeam(team, user, utils.GetSiteURL()); err != nil {
CommandPrintErrorln("Unable to add '" + userArg + "' to " + team.Name)
}
}
diff --git a/einterfaces/saml.go b/einterfaces/saml.go
index af2e815a5..478cf8a68 100644
--- a/einterfaces/saml.go
+++ b/einterfaces/saml.go
@@ -10,7 +10,7 @@ import (
type SamlInterface interface {
ConfigureSP() *model.AppError
BuildRequest(relayState string) (*model.SamlAuthRequest, *model.AppError)
- DoLogin(encodedXML string, relayState map[string]string) (*model.User, *model.AppError)
+ DoLogin(encodedXML string, relayState map[string]string, siteURL string) (*model.User, *model.AppError)
GetMetadata() (string, *model.AppError)
}
diff --git a/i18n/de.json b/i18n/de.json
index ff4b6016b..083a1ff7a 100644
--- a/i18n/de.json
+++ b/i18n/de.json
@@ -221,11 +221,11 @@
},
{
"id": "api.channel.create_group.bad_size.app_error",
- "translation": "Group message channels must contain at least 3 and no more than 8 users"
+ "translation": "Gruppennachrichtenkanäle müssen aus mindestens 3 und nicht mehr als 8 Benutzer bestehen"
},
{
"id": "api.channel.create_group.bad_user.app_error",
- "translation": "One of the provided users does not exist"
+ "translation": "Einer der angegebenen Benutzer existiert nicht"
},
{
"id": "api.channel.delete_channel.archived",
@@ -901,7 +901,7 @@
},
{
"id": "api.email_batching.render_batched_post.group_message",
- "translation": "Group Message"
+ "translation": "Gruppennachricht"
},
{
"id": "api.email_batching.render_batched_post.sender.app_error",
@@ -1516,6 +1516,10 @@
"translation": "Initialisiere API-Routen für Nachrichten"
},
{
+ "id": "api.post.link_preview_disabled.app_error",
+ "translation": "Link Vorschauen wurden vom Systemadministrator deaktiviert"
+ },
+ {
"id": "api.post.make_direct_channel_visible.get_2_members.error",
"translation": "Fehler beim Abruf der 2 Mitglieder für den Direkt-Kanal channel_id={{.ChannelId}}"
},
@@ -1817,11 +1821,11 @@
},
{
"id": "api.slackimport.slack_add_users.missing_email_address",
- "translation": "User {{.Username}} does not have an email address in the Slack export. Using {{.Email}} as a placeholder. The user should update their email address once logged in to the system.\r\n"
+ "translation": "Der Benutzer {{.Username}} hat keine E-Mail-Adresse im Slack Export. Verwende {{.Email}} als Platzhalter. Der Benutzer sollte seine E-Mail-Adresse aktualisieren sobald er sich angemeldet hat.\r\n"
},
{
"id": "api.slackimport.slack_add_users.missing_email_address.warn",
- "translation": "User {{.Username}} does not have an email address in the Slack export. Using {{.Email}} as a placeholder. The user should update their email address once logged in to the system."
+ "translation": "Der Benutzer {{.Username}} hat keine E-Mail-Adresse im Slack Export. Verwende {{.Email}} als Platzhalter. Der Benutzer sollte seine E-Mail-Adresse aktualisieren sobald er sich angemeldet hat."
},
{
"id": "api.slackimport.slack_add_users.unable_import",
@@ -2037,7 +2041,7 @@
},
{
"id": "api.templates.channel_name.group",
- "translation": "Group Message"
+ "translation": "Gruppennachricht"
},
{
"id": "api.templates.email_change_body.info",
@@ -2169,11 +2173,11 @@
},
{
"id": "api.templates.post_subject_in_direct_message",
- "translation": "{{.SubjectText}} bei {{.TeamDisplayName}} von {{.SenderDisplayName}} am {{.Day}}.{{.Month}}.{{.Year}}"
+ "translation": "{{.SubjectText}} von {{.SenderDisplayName}} am {{.Day}}.{{.Month}}.{{.Year}}"
},
{
"id": "api.templates.post_subject_in_group_message",
- "translation": "{{.SubjectText}} bei {{.TeamDisplayName}} von {{.SenderDisplayName}} am {{.Day}}.{{.Month}}.{{.Year}}"
+ "translation": "Neue Gruppennachricht von {{.SenderDisplayName}} am {{.Day}}.{{.Month}}.{{.Year}}"
},
{
"id": "api.templates.reset_body.button",
@@ -2953,7 +2957,7 @@
},
{
"id": "app.import.validate_post_import_data.message_length.error",
- "translation": "Post Message property is longer than the maximum permitted length."
+ "translation": "Message Eigenschaft der Nachricht ist länger als die maximal erlaubte Länge."
},
{
"id": "app.import.validate_post_import_data.message_missing.error",
@@ -3081,11 +3085,11 @@
},
{
"id": "authentication.permissions.create_group_channel.description",
- "translation": "Ability to create new group message channels"
+ "translation": "Die Möglichkeit, neue Gruppennachrichtenkanäle zu erstellen"
},
{
"id": "authentication.permissions.create_group_channel.name",
- "translation": "Create Group Message"
+ "translation": "Gruppennachrichten erstellen"
},
{
"id": "authentication.permissions.create_team_roles.description",
@@ -5097,7 +5101,7 @@
},
{
"id": "store.sql_post.search.warn",
- "translation": "Query error searching posts: %v"
+ "translation": "Abfragefehler bei der Suche nach Nachrichten: %v"
},
{
"id": "store.sql_post.update.app_error",
diff --git a/i18n/en.json b/i18n/en.json
index 55c3bb7ed..9c8921985 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -1548,6 +1548,10 @@
"translation": "Initializing post API routes"
},
{
+ "id": "api.post.link_preview_disabled.app_error",
+ "translation": "Link previews have been disabled by the system administrator."
+ },
+ {
"id": "api.post.make_direct_channel_visible.get_2_members.error",
"translation": "Failed to get 2 members for a direct channel channel_id={{.ChannelId}}"
},
diff --git a/i18n/es.json b/i18n/es.json
index 001ced420..8dc5f28de 100644
--- a/i18n/es.json
+++ b/i18n/es.json
@@ -1516,6 +1516,10 @@
"translation": "Inicializando rutas del API para los mensajes"
},
{
+ "id": "api.post.link_preview_disabled.app_error",
+ "translation": "Vistas previas de los enlaces han sido deshabilitadas por el administrador del sistema."
+ },
+ {
"id": "api.post.make_direct_channel_visible.get_2_members.error",
"translation": "Falla al obtener 2 miembros para un canal directo channel_id={{.ChannelId}}"
},
diff --git a/i18n/fr.json b/i18n/fr.json
index 894edf7e5..847c7decd 100644
--- a/i18n/fr.json
+++ b/i18n/fr.json
@@ -181,7 +181,7 @@
},
{
"id": "api.channel.can_manage_channel.private_restricted_system_admin.app_error",
- "translation": "La création et l'administration de groupes privés sont réservées aux administrateurs systèmes."
+ "translation": "La création et l'administration de groupes privés sont réservées aux administrateurs système."
},
{
"id": "api.channel.can_manage_channel.private_restricted_team_admin.app_error",
@@ -189,7 +189,7 @@
},
{
"id": "api.channel.can_manage_channel.public_restricted_system_admin.app_error",
- "translation": "La création et l'administration du canal public sont réservées aux administrateurs systèmes."
+ "translation": "La création et l'administration du canal public sont réservées aux administrateurs système."
},
{
"id": "api.channel.can_manage_channel.public_restricted_team_admin.app_error",
@@ -217,15 +217,15 @@
},
{
"id": "api.channel.create_direct_channel.invalid_user.app_error",
- "translation": "Invalid user ID for direct channel creation"
+ "translation": "ID utilisateur invalide pour la création directe du canal"
},
{
"id": "api.channel.create_group.bad_size.app_error",
- "translation": "Group message channels must contain at least 3 and no more than 8 users"
+ "translation": "Les canaux dédiés aux messages de groupe doivent contenir au moins 3 et pas plus de 8 utilisateurs"
},
{
"id": "api.channel.create_group.bad_user.app_error",
- "translation": "One of the provided users does not exist"
+ "translation": "Un des utilisateurs fournis n'existe pas"
},
{
"id": "api.channel.delete_channel.archived",
@@ -241,7 +241,7 @@
},
{
"id": "api.channel.delete_channel.failed_post.error",
- "translation": "Impossible d'envoyer le message archivé %v"
+ "translation": "Impossible d'envoyer le message d'archive %v"
},
{
"id": "api.channel.delete_channel.failed_send.app_error",
@@ -257,7 +257,7 @@
},
{
"id": "api.channel.delete_channel.permissions.app_error",
- "translation": "Vous n'avez pas les permissions nécessaires"
+ "translation": "Vous n'avez pas les permissions requises"
},
{
"id": "api.channel.get_channel.wrong_team.app_error",
@@ -285,7 +285,7 @@
},
{
"id": "api.channel.join_channel.permissions.app_error",
- "translation": "Vous n'avez pas les droits requis"
+ "translation": "Vous n'avez pas les permissions requises"
},
{
"id": "api.channel.join_channel.post_and_forget",
@@ -309,19 +309,19 @@
},
{
"id": "api.channel.post_update_channel_displayname_message_and_forget.create_post.error",
- "translation": "Echec de l'envoi de la mise à jour du message de %v"
+ "translation": "Impossible de publier le message de mise à jour du nom d'affichage"
},
{
"id": "api.channel.post_update_channel_displayname_message_and_forget.retrieve_user.error",
- "translation": "Impossible de récupérer l'utilisateur lors de l'enregistrement d'un nouveau message de canal %v"
+ "translation": "Impossible de récupérer l'utilisateur lors de la mise à jour du champ du nom d'affichage du canal"
},
{
"id": "api.channel.post_update_channel_displayname_message_and_forget.updated_from",
- "translation": "%s a mis à jour l'en-tête du canal de : %s en : %s"
+ "translation": "%s a mis à jour l'entête du canal de : %s en : %s"
},
{
"id": "api.channel.post_update_channel_header_message_and_forget.post.error",
- "translation": "Failed to post update channel header message"
+ "translation": "Impossible de publier le message de mise à jour de l'entête du canal"
},
{
"id": "api.channel.post_update_channel_header_message_and_forget.removed",
@@ -329,19 +329,19 @@
},
{
"id": "api.channel.post_update_channel_header_message_and_forget.retrieve_user.error",
- "translation": "Impossible de récupérer l'utilisateur lors de l'enregistrement d'un nouveau message de canal %v"
+ "translation": "Impossible de récupérer l'utilisateur lors de la mise à jour de l'entête du canal"
},
{
"id": "api.channel.post_update_channel_header_message_and_forget.updated_from",
- "translation": "%s a mis à jour l'en-tête du canal de : %s en : %s"
+ "translation": "%s a mis à jour l'entête du canal de : %s en : %s"
},
{
"id": "api.channel.post_update_channel_header_message_and_forget.updated_to",
- "translation": "%s a mis à jour l'en-tête du canal en : %s"
+ "translation": "%s a mis à jour l'entête du canal en : %s"
},
{
"id": "api.channel.post_user_add_remove_message_and_forget.error",
- "translation": "Erreur lors de l'envoi du message joindre/quitter %v"
+ "translation": "Impossible de publier le message joindre/quitter"
},
{
"id": "api.channel.remove.default.app_error",
@@ -349,7 +349,7 @@
},
{
"id": "api.channel.remove_member.permissions.app_error",
- "translation": "Vous n'avez pas les droits requis "
+ "translation": "Vous n'avez pas les permissions requises "
},
{
"id": "api.channel.remove_member.removed",
@@ -373,7 +373,7 @@
},
{
"id": "api.channel.update_channel.permission.app_error",
- "translation": "Vous n'avez pas les droits requis"
+ "translation": "Vous n'avez pas les permissions requises"
},
{
"id": "api.channel.update_channel.tried.app_error",
@@ -389,7 +389,7 @@
},
{
"id": "api.command.delete.app_error",
- "translation": "Droits insuffisants pour supprimer la commande"
+ "translation": "Permissions insuffisantes pour supprimer la commande"
},
{
"id": "api.command.disabled.app_error",
@@ -461,7 +461,7 @@
},
{
"id": "api.command.regen.app_error",
- "translation": "Droits insuffisants pour regénérer le jeton de commande"
+ "translation": "Permissions insuffisantes pour regénérer le jeton de commande"
},
{
"id": "api.command.team_mismatch.app_error",
@@ -469,7 +469,7 @@
},
{
"id": "api.command.update.app_error",
- "translation": "Droits insuffisants pour mettre à jour la commande"
+ "translation": "Permissions insuffisantes pour mettre à jour la commande"
},
{
"id": "api.command_away.desc",
@@ -785,7 +785,7 @@
},
{
"id": "api.command_shortcuts.nav.unread_prev",
- "translation": "ALT+MAJ+HAUT: Canal ou message précédent de la barre latérale gauche comportant des messages non lus\n"
+ "translation": "ALT+MAJ+HAUT: Canal ou message privé précédents de la barre latérale gauche comportant des messages non lus\n"
},
{
"id": "api.command_shrug.desc",
@@ -805,7 +805,7 @@
},
{
"id": "api.context.invalid_body_param.app_error",
- "translation": "Invalid or missing {{.Name}} in request body"
+ "translation": "{{.Name}} invalid ou manquant dans le corps de la requête"
},
{
"id": "api.context.invalid_param.app_error",
@@ -813,7 +813,7 @@
},
{
"id": "api.context.invalid_session.error",
- "translation": "Invalid session err=%v"
+ "translation": "Session invalide err=%v"
},
{
"id": "api.context.invalid_team_url.debug",
@@ -821,11 +821,11 @@
},
{
"id": "api.context.invalid_token.error",
- "translation": "Invalid session token={{.Token}}, err={{.Error}}"
+ "translation": "Jeton de session invalide={{.Token}}, err={{.Error}}"
},
{
"id": "api.context.invalid_url_param.app_error",
- "translation": "Invalid or missing {{.Name}} parameter in request URL"
+ "translation": "Paramètre {{.Name}} invalide ou manquant dans l'URL de la requête"
},
{
"id": "api.context.invalidate_all_caches",
@@ -849,7 +849,7 @@
},
{
"id": "api.context.permissions.app_error",
- "translation": "Vous n'avez pas les permissions appropriées"
+ "translation": "Vous n'avez pas les permissions requises"
},
{
"id": "api.context.session_expired.app_error",
@@ -857,7 +857,7 @@
},
{
"id": "api.context.system_permissions.app_error",
- "translation": "Vous n'avez pas les permissions appropriées (système)"
+ "translation": "Vous n'avez pas les permissions requises (système)"
},
{
"id": "api.context.token_provided.app_error",
@@ -901,7 +901,7 @@
},
{
"id": "api.email_batching.render_batched_post.group_message",
- "translation": "Group Message"
+ "translation": "Message de groupe"
},
{
"id": "api.email_batching.render_batched_post.sender.app_error",
@@ -935,7 +935,7 @@
},
{
"id": "api.email_batching.start.starting",
- "translation": "Début de l'envoi d'e-mails groupés. Vérification des e-mails en attente toutes les %v secondes."
+ "translation": "Début de l'envoi d'e-mails par lot. Vérification des e-mails en attente toutes les %v secondes."
},
{
"id": "api.emoji.create.duplicate.app_error",
@@ -947,7 +947,7 @@
},
{
"id": "api.emoji.create.permissions.app_error",
- "translation": "Droits insuffisants pour créer des émoticônes."
+ "translation": "Permissions insuffisantes pour créer des émoticônes."
},
{
"id": "api.emoji.create.too_large.app_error",
@@ -959,7 +959,7 @@
},
{
"id": "api.emoji.delete.permissions.app_error",
- "translation": "Droits insuffisants pour supprimer des émoticônes."
+ "translation": "Permissions insuffisantes pour supprimer des émoticônes."
},
{
"id": "api.emoji.disabled.app_error",
@@ -1167,7 +1167,7 @@
},
{
"id": "api.file.upload_file.bad_parse.app_error",
- "translation": "Unable to upload file. Header cannot be parsed."
+ "translation": "Impossible d'envoyer le fichier. L'entête ne peut être analysé."
},
{
"id": "api.file.upload_file.large_image.app_error",
@@ -1307,7 +1307,7 @@
},
{
"id": "api.oauth.complete_oauth.missing_code.app_error",
- "translation": "Le fournisseur de services {{.service}} n'a pas envoyé un code d'autorisation dans l'URL de redirection.\n\nPour [Google Apps](https://docs.mattermost.com/deployment/sso-google.html) vérifiez que votre administrateur a activé l'API Google+.\n\nPour [Office 365](https://docs.mattermost.com/deployment/sso-office.html) vérifiez que l'administrateur de votre organisation Microsoft a activé l'application Mattermost.\n\nPour [GitLab](https://docs.mattermost.com/deployment/sso-gitlab.html) verifiez que vous avez suivi les instructions d'installation.\n\nSi malgré cela vous avez toujours des problèmes avec votre configuration, postez un message sur le [forum de dépannage](https://forum.mattermost.org/c/general/trouble-shoot) où nous aidons à résoudre les problèmes d'installation."
+ "translation": "Le fournisseur de services {{.service}} n'a pas envoyé un code d'autorisation dans l'URL de redirection.\n\nPour [Google Apps](https://docs.mattermost.com/deployment/sso-google.html) vérifiez que votre administrateur a activé l'API Google+.\n\nPour [Office 365](https://docs.mattermost.com/deployment/sso-office.html) vérifiez que l'administrateur de votre organisation Microsoft a activé l'application Mattermost.\n\nPour [GitLab](https://docs.mattermost.com/deployment/sso-gitlab.html) verifiez que vous avez suivi les instructions d'installation.\n\nSi malgré cela vous avez toujours des problèmes avec votre configuration, publiez un message sur le [forum de dépannage](https://forum.mattermost.org/c/general/trouble-shoot) où nous aidons à résoudre les problèmes d'installation."
},
{
"id": "api.oauth.delete.permissions.app_error",
@@ -1427,7 +1427,7 @@
},
{
"id": "api.post.create_post.can_not_post_to_deleted.error",
- "translation": "Impossible de poster un message dans un canal supprimé."
+ "translation": "Impossible de publier un message dans un canal supprimé."
},
{
"id": "api.post.create_post.channel_root_id.app_error",
@@ -1455,7 +1455,7 @@
},
{
"id": "api.post.delete_post.permissions.app_error",
- "translation": "Vous n'avez pas les permissions appropriées"
+ "translation": "Vous n'avez pas les permissions requises"
},
{
"id": "api.post.delete_post_files.app_error.warn",
@@ -1497,7 +1497,7 @@
},
{
"id": "api.post.get_post.permissions.app_error",
- "translation": "Vous n'avez pas les permissions appropriées"
+ "translation": "Vous n'avez pas les permissions requises"
},
{
"id": "api.post.handle_post_events_and_forget.members.error",
@@ -1516,8 +1516,12 @@
"translation": "Initialisation des routes de l'API des messages"
},
{
+ "id": "api.post.link_preview_disabled.app_error",
+ "translation": "Les prévisualisations de liens ont été désactivées par l'administrateur système."
+ },
+ {
"id": "api.post.make_direct_channel_visible.get_2_members.error",
- "translation": "Impossible de récupérer 2 membres pour un canal de messages privés channel_id=%v"
+ "translation": "Impossible de récupérer 2 membres pour un canal de messages privés channel_id={{.ChannelId}}"
},
{
"id": "api.post.make_direct_channel_visible.get_members.error",
@@ -1537,7 +1541,7 @@
},
{
"id": "api.post.send_notifications.user_id.debug",
- "translation": "Post creator not in channel for the post, no notification sent post_id=%v channel_id=%v user_id=%v"
+ "translation": "Le créateur du message n'est pas dans le même canal que le message, aucune notification n'a été envoyée post_id=%v channel_id=%v user_id=%v"
},
{
"id": "api.post.send_notifications_and_forget.clear_push_notification.debug",
@@ -1589,7 +1593,7 @@
},
{
"id": "api.post.send_notifications_and_forget.push_notification.error",
- "translation": "Failed to send push device_id={{.DeviceId}}, err={{.Error}}"
+ "translation": "Impossible d'envoyer la notification push device_id={{.DeviceId}}, err={{.Error}}"
},
{
"id": "api.post.send_notifications_and_forget.sent",
@@ -1605,11 +1609,11 @@
},
{
"id": "api.post.update_post.permissions.app_error",
- "translation": "Vous n'avez pas les permissions appropriées"
+ "translation": "Vous n'avez pas les permissions requises"
},
{
"id": "api.post.update_post.permissions_denied.app_error",
- "translation": "La création d'équipes est désactivée. Veuillez demander les détails à votre administrateur système."
+ "translation": "L'édition des messages a été désactivée. Pour plus d'infos, veuillez demander à votre administrateur système."
},
{
"id": "api.post.update_post.permissions_details.app_error",
@@ -1617,7 +1621,7 @@
},
{
"id": "api.post.update_post.permissions_time_limit.app_error",
- "translation": "Post edit is only allowed for {{.timeLimit}} seconds. Please ask your systems administrator for details."
+ "translation": "L'édition de messages est seulement autorisée pour {{.timeLimit}} secondes. Pour plus d'infos, veuillez demander à votre administrateur système."
},
{
"id": "api.post.update_post.system_message.app_error",
@@ -1817,11 +1821,11 @@
},
{
"id": "api.slackimport.slack_add_users.missing_email_address",
- "translation": "User {{.Username}} does not have an email address in the Slack export. Using {{.Email}} as a placeholder. The user should update their email address once logged in to the system.\r\n"
+ "translation": "L'exportation Slack ne dispose pas d'une adresse e-mail pour l'utilisateur {{.Username}}. Utilisation de {{.Email}} comme remplacement. L'utilisateur devra mettre à jour son adresse e-mail une fois connecté au système.\r\n"
},
{
"id": "api.slackimport.slack_add_users.missing_email_address.warn",
- "translation": "User {{.Username}} does not have an email address in the Slack export. Using {{.Email}} as a placeholder. The user should update their email address once logged in to the system."
+ "translation": "L'exportation Slack ne dispose pas d'une adresse e-mail pour l'utilisateur {{.Username}}. Utilisation de {{.Email}} comme remplacement. L'utilisateur devra mettre à jour son adresse e-mail une fois connecté au système."
},
{
"id": "api.slackimport.slack_add_users.unable_import",
@@ -2033,11 +2037,11 @@
},
{
"id": "api.team.update_team.permissions.app_error",
- "translation": "Vous n'avez pas les permissions appropriées"
+ "translation": "Vous n'avez pas les permissions requises"
},
{
"id": "api.templates.channel_name.group",
- "translation": "Group Message"
+ "translation": "Message de groupe"
},
{
"id": "api.templates.email_change_body.info",
@@ -2049,7 +2053,7 @@
},
{
"id": "api.templates.email_change_subject",
- "translation": "[{{ .SiteName }}] Your email address has changed"
+ "translation": "[{{ .SiteName }}] Votre adresse e-mail a été changée"
},
{
"id": "api.templates.email_change_verify_body.button",
@@ -2065,7 +2069,7 @@
},
{
"id": "api.templates.email_change_verify_subject",
- "translation": "[{{ .SiteName }}] Verify new email address"
+ "translation": "[{{ .SiteName }}] Vérification de la nouvelle adresse e-mail"
},
{
"id": "api.templates.email_footer",
@@ -2121,7 +2125,7 @@
},
{
"id": "api.templates.invite_subject",
- "translation": "[{{ .SiteName }}] {{ .SenderName }} invited you to join {{ .TeamDisplayName }} Team"
+ "translation": "[{{ .SiteName }}] {{ .SenderName }} vous a invité à rejoindre l'équipe {{ .TeamDisplayName }}"
},
{
"id": "api.templates.mfa_activated_body.info",
@@ -2133,7 +2137,7 @@
},
{
"id": "api.templates.mfa_change_subject",
- "translation": "[{{ .SiteName }}] Your MFA has been updated"
+ "translation": "[{{ .SiteName }}] Votre authentification multi-facteurs (MFA) a été mise à jour"
},
{
"id": "api.templates.mfa_deactivated_body.info",
@@ -2153,7 +2157,7 @@
},
{
"id": "api.templates.password_change_subject",
- "translation": "[{{ .SiteName }}] Your password has been updated"
+ "translation": "[{{ .SiteName }}] Votre mot de passe a été mis à jour"
},
{
"id": "api.templates.post_body.button",
@@ -2169,11 +2173,11 @@
},
{
"id": "api.templates.post_subject_in_direct_message",
- "translation": "{{.SubjectText}} sur {{.TeamDisplayName}} le {{.Day}} {{.Month}} {{.Year}}"
+ "translation": "{{.SubjectText}} de {{.SenderDisplayName}} du {{.Day}} {{.Month}} {{.Year}}"
},
{
"id": "api.templates.post_subject_in_group_message",
- "translation": "{{.SubjectText}} sur {{.TeamDisplayName}} le {{.Day}} {{.Month}} {{.Year}}"
+ "translation": "Nouveau message de groupe de {{.SenderDisplayName}} du {{.Day}} {{.Month}} {{.Year}}"
},
{
"id": "api.templates.reset_body.button",
@@ -2189,11 +2193,11 @@
},
{
"id": "api.templates.reset_subject",
- "translation": "[{{ .SiteName }}] Reset your password"
+ "translation": "[{{ .SiteName }}] Réinitialisez votre mot de passe"
},
{
"id": "api.templates.signin_change_email.body.info",
- "translation": "Vous avez mis à jour votre méthode de connexion pour le {{ .SiteName }} à {{.Method}}.<br>Si vous n'êtes pas à l'origine de ce changement, veuillez contacter votre administrateur système."
+ "translation": "Vous avez mis à jour votre méthode de connexion en {{.Method}} pour {{ .SiteName }}.<br>Si vous n'êtes pas à l'origine de ce changement, veuillez contacter votre administrateur système."
},
{
"id": "api.templates.signin_change_email.body.method_email",
@@ -2205,7 +2209,7 @@
},
{
"id": "api.templates.signin_change_email.subject",
- "translation": "[{{ .SiteName }}] You updated your sign-in method on {{ .SiteName }}"
+ "translation": "[{{ .SiteName }}] Votre méthode de connexion a été mise à jour sur {{ .SiteName }}"
},
{
"id": "api.templates.signup_team_body.button",
@@ -2241,7 +2245,7 @@
},
{
"id": "api.templates.username_change_subject",
- "translation": "[{{ .SiteName }}] Your username has changed"
+ "translation": "[{{ .SiteName }}] Votre nom d'utilisateur a changé"
},
{
"id": "api.templates.verify_body.button",
@@ -2285,7 +2289,7 @@
},
{
"id": "api.templates.welcome_subject",
- "translation": "[{{ .SiteName }}] You joined {{ .ServerURL }}"
+ "translation": "[{{ .SiteName }}] Vous avez rejoint {{ .ServerURL }}"
},
{
"id": "api.user.activate_mfa.email_and_ldap_only.app_error",
@@ -2293,7 +2297,7 @@
},
{
"id": "api.user.add_direct_channels_and_forget.failed.error",
- "translation": "Failed to add direct channel preferences for user user_id={{.UserId}}, team_id={{.TeamId}}, err={{.Error}}"
+ "translation": "Impossible de spécifier les préférences du canal de messages directs pour l'utilisateur user_id={{.UserId}}, team_id={{.TeamId}}, err={{.Error}}"
},
{
"id": "api.user.authorize_oauth_user.bad_response.app_error",
@@ -2389,7 +2393,7 @@
},
{
"id": "api.user.create_user.disabled.app_error",
- "translation": "User creation is disabled."
+ "translation": "La création d'utilisateurs est désactivée."
},
{
"id": "api.user.create_user.joining.error",
@@ -2549,19 +2553,19 @@
},
{
"id": "api.user.send_email_change_email_and_forget.error",
- "translation": "Impossible d'envoyer l'e-mail de notification de changement d'adresse e-mail err=%v"
+ "translation": "Impossible d'envoyer l'e-mail de notification de changement d'adresse e-mail"
},
{
"id": "api.user.send_email_change_username_and_forget.error",
- "translation": "Impossible d'envoyer l'e-mail de changement de nom d'utilisateur err=%v"
+ "translation": "Impossible d'envoyer l'e-mail de changement de nom d'utilisateur"
},
{
"id": "api.user.send_email_change_verify_email_and_forget.error",
- "translation": "Impossible d'envoyer l'e-mail de vérification de changement d'adresse e-mail err=%v"
+ "translation": "Impossible d'envoyer l'e-mail de vérification de changement d'adresse e-mail"
},
{
"id": "api.user.send_password_change_email_and_forget.error",
- "translation": "Impossible d'envoyer l'e-mail de mise à jour du mot de passe err=%v"
+ "translation": "Impossible d'envoyer l'e-mail de mise à jour du mot de passe"
},
{
"id": "api.user.send_password_reset.find.app_error",
@@ -2577,15 +2581,15 @@
},
{
"id": "api.user.send_sign_in_change_email_and_forget.error",
- "translation": "Impossible d'envoyer l'e-mail de mise à jour du mot de passe err=%v"
+ "translation": "Impossible d'envoyer l'e-mail de mise à jour du mot de passe"
},
{
"id": "api.user.send_verify_email_and_forget.failed.error",
- "translation": "Impossible d'envoyer l'e-mail de vérification err=%v"
+ "translation": "Impossible d'envoyer l'e-mail de vérification"
},
{
"id": "api.user.send_welcome_email_and_forget.failed.error",
- "translation": "Impossible d'envoyer l'e-mail de bienvenue err=%v"
+ "translation": "Impossible d'envoyer l'e-mail de bienvenue"
},
{
"id": "api.user.update_active.no_deactivate_ldap.app_error",
@@ -2593,7 +2597,7 @@
},
{
"id": "api.user.update_active.permissions.app_error",
- "translation": "Vous n'avez pas les permissions appropriées"
+ "translation": "Vous n'avez pas les permissions requises"
},
{
"id": "api.user.update_mfa.not_available.app_error",
@@ -2601,7 +2605,7 @@
},
{
"id": "api.user.update_oauth_user_attrs.get_user.app_error",
- "translation": "Impossible de créer un utilisateur à partir du user object {{.Service}}"
+ "translation": "Impossible de récupérer l'utilisateur à partir de l'objet utilisateur {{.Service}}"
},
{
"id": "api.user.update_password.context.app_error",
@@ -2633,7 +2637,7 @@
},
{
"id": "api.user.update_roles.permissions.app_error",
- "translation": "Vous n'avez pas les permissions appropriées"
+ "translation": "Vous n'avez pas les permissions requises"
},
{
"id": "api.user.update_roles.system_admin_needed.app_error",
@@ -2725,7 +2729,7 @@
},
{
"id": "api.webhook.create_outgoing.disabled.app_error",
- "translation": "Les webhooks entrants ont été désactivés par l'administrateur système."
+ "translation": "Les webhooks sortants ont été désactivés par l'administrateur système."
},
{
"id": "api.webhook.create_outgoing.intersect.app_error",
@@ -2737,7 +2741,7 @@
},
{
"id": "api.webhook.create_outgoing.permissions.app_error",
- "translation": "Droits insuffisants pour créer le webhook sortant."
+ "translation": "Permissions insuffisantes pour créer le webhook sortant."
},
{
"id": "api.webhook.create_outgoing.triggers.app_error",
@@ -2749,7 +2753,7 @@
},
{
"id": "api.webhook.delete_incoming.permissions.app_error",
- "translation": "Droits insuffisants pour supprimer le webhook entrant"
+ "translation": "Permissions insuffisantes pour supprimer le webhook entrant"
},
{
"id": "api.webhook.delete_outgoing.disabled.app_error",
@@ -2757,7 +2761,7 @@
},
{
"id": "api.webhook.delete_outgoing.permissions.app_error",
- "translation": "Droits insuffisants pour supprimer le webhook sortant"
+ "translation": "Permissions insuffisantes pour supprimer le webhook sortant"
},
{
"id": "api.webhook.incoming.debug",
@@ -2773,7 +2777,7 @@
},
{
"id": "api.webhook.regen_outgoing_token.permissions.app_error",
- "translation": "Droits insuffisants pour regénérer le jeton du webhook sortant"
+ "translation": "Permissions insuffisantes pour regénérer le jeton du webhook sortant"
},
{
"id": "api.webhook.team_mismatch.app_error",
@@ -2785,11 +2789,11 @@
},
{
"id": "api.webhook.update_incoming.permissions.app_error",
- "translation": "Droits insuffisants pour supprimer le webhook entrant"
+ "translation": "Permissions insuffisantes pour mettre à jour le webhook entrant"
},
{
"id": "api.webhook.update_outgoing.disabled.app_error",
- "translation": "Les webhooks entrants ont été désactivés par l'administrateur système."
+ "translation": "Les webhooks sortants ont été désactivés par l'administrateur système."
},
{
"id": "api.webhook.update_outgoing.intersect.app_error",
@@ -2797,11 +2801,11 @@
},
{
"id": "api.webhook.update_outgoing.not_open.app_error",
- "translation": "Les webhooks sortants ne peuvent être créés que pour les canaux publics."
+ "translation": "Les webhooks sortants ne peuvent être mis à jour que pour les canaux publics."
},
{
"id": "api.webhook.update_outgoing.permissions.app_error",
- "translation": "Droits insuffisants pour créer le webhook sortant."
+ "translation": "Permissions insuffisantes pour mettre à jour le webhook sortant."
},
{
"id": "api.webhook.update_outgoing.triggers.app_error",
@@ -2821,7 +2825,7 @@
},
{
"id": "api.websocket.invalid_session.error",
- "translation": "Invalid session err=%v"
+ "translation": "Session invalide err=%v"
},
{
"id": "api.websocket_handler.invalid_param.app_error",
@@ -2829,279 +2833,279 @@
},
{
"id": "app.channel.create_channel.no_team_id.app_error",
- "translation": "Must specify the team ID to create a channel"
+ "translation": "Veuillez spécifier l'identifiant d'équipe afin de créer un canal"
},
{
"id": "app.channel.post_update_channel_purpose_message.post.error",
- "translation": "Failed to post channel purpose message"
+ "translation": "Impossible de publier le message de description du canal"
},
{
"id": "app.channel.post_update_channel_purpose_message.removed",
- "translation": "%s a supprimé le titre du canal (était : %s)"
+ "translation": "%s a supprimé la description du canal (précédemment : %s)"
},
{
"id": "app.channel.post_update_channel_purpose_message.retrieve_user.error",
- "translation": "Impossible de récupérer l'utilisateur lors de l'enregistrement d'un nouveau message de canal %v"
+ "translation": "Impossible de récupérer l'utilisateur lors de la mise à jour du message de description du canal %v"
},
{
"id": "app.channel.post_update_channel_purpose_message.updated_from",
- "translation": "%s a mis à jour l'en-tête du canal de : %s en : %s"
+ "translation": "%s a mis à jour le message de description du canal de : %s en : %s"
},
{
"id": "app.channel.post_update_channel_purpose_message.updated_to",
- "translation": "%s a mis à jour l'en-tête du canal en : %s"
+ "translation": "%s a mis à jour le message de description du canal en : %s"
},
{
"id": "app.import.bulk_import.file_scan.error",
- "translation": "Error reading import data file."
+ "translation": "Erreur lors de la lecture du fichier d'importation de données"
},
{
"id": "app.import.bulk_import.json_decode.error",
- "translation": "JSON decode of line failed."
+ "translation": "Le décodage d'une ligne du fichier JSON a échoué"
},
{
"id": "app.import.import_channel.team_not_found.error",
- "translation": "Error importing channel. Team with name \"{{.TeamName}}\" could not be found."
+ "translation": "Erreur lors de l'importation du canal. L'équipe portant le nom \"{{.TeamName}}\" n'a pas pu être trouvée."
},
{
"id": "app.import.import_line.null_channel.error",
- "translation": "Import data line has type \"channel\" but the channel object is null."
+ "translation": "La ligne de données importée dispose d'un type \"channel\", mais l'objet channel est null."
},
{
"id": "app.import.import_line.null_post.error",
- "translation": "Import data line has type \"post\" but the post object is null."
+ "translation": "La ligne de données importée dispose d'un type \"post\", mais l'objet post est null."
},
{
"id": "app.import.import_line.null_team.error",
- "translation": "Import data line has type \"team\" but the team object is null."
+ "translation": "La ligne de données importée dispose d'un type \"team\", mais l'objet team est null."
},
{
"id": "app.import.import_line.null_user.error",
- "translation": "Import data line has type \"user\" but the user object is null."
+ "translation": "La ligne de données importée dispose d'un type \"user\", mais l'objet user est null."
},
{
"id": "app.import.import_line.unknown_line_type.error",
- "translation": "Import data line has unknown type \"{{.Type}}\"."
+ "translation": "La ligne de données importée dispose d'un type inconnu \"{{.Type}}\"."
},
{
"id": "app.import.import_post.channel_not_found.error",
- "translation": "Error importing post. Channel with name \"{{.ChannelName}}\" could not be found."
+ "translation": "Erreur lors de l'importation du message. Le canal portant le nom \"{{.ChannelName}}\" n'a pas pu être trouvé."
},
{
"id": "app.import.import_post.team_not_found.error",
- "translation": "Error importing post. Team with name \"{{.TeamName}}\" could not be found."
+ "translation": "Erreur lors de l'importation du message. L'équipe portant le nom \"{{.TeamName}}\" n'a pas pu être trouvée."
},
{
"id": "app.import.import_post.user_not_found.error",
- "translation": "Error importing post. User with username \"{{.Username}}\" could not be found."
+ "translation": "Erreur lors de l'importation du message. L'utilisateur portant le nom \"{{.Username}}\" n'a pas pu être trouvé."
},
{
"id": "app.import.validate_channel_import_data.create_at_zero.error",
- "translation": "Channel create_at must not be 0 if provided."
+ "translation": "La propriété de canal create_at ne doit pas être 0 si ce champ est fourni."
},
{
"id": "app.import.validate_channel_import_data.display_name_length.error",
- "translation": "Channel display_name is not within permitted length constraints."
+ "translation": "La propriété de canal display_name ne respecte pas les contraintes de longueur autorisées."
},
{
"id": "app.import.validate_channel_import_data.display_name_missing.error",
- "translation": "Missing required channel property: display_name."
+ "translation": "La propriété de canal requise est manquante: display_name."
},
{
"id": "app.import.validate_channel_import_data.header_length.error",
- "translation": "Channel header is too long."
+ "translation": "L'entête du canal est trop long."
},
{
"id": "app.import.validate_channel_import_data.name_characters.error",
- "translation": "Channel name contains invalid characters."
+ "translation": "Le nom du canal contient des caractères invalides."
},
{
"id": "app.import.validate_channel_import_data.name_length.error",
- "translation": "Channel name is too long."
+ "translation": "Le nom du canal est trop long."
},
{
"id": "app.import.validate_channel_import_data.name_missing.error",
- "translation": "Missing required channel property: name"
+ "translation": "La propriété de canal requise est manquante: name"
},
{
"id": "app.import.validate_channel_import_data.purpose_length.error",
- "translation": "Channel purpose is too long."
+ "translation": "La description du canal est trop longue."
},
{
"id": "app.import.validate_channel_import_data.team_missing.error",
- "translation": "Missing required channel property: team"
+ "translation": "La propriété de canal requise est manquante: team"
},
{
"id": "app.import.validate_channel_import_data.type_invalid.error",
- "translation": "Channel type is invalid."
+ "translation": "Type de canal invalide."
},
{
"id": "app.import.validate_channel_import_data.type_missing.error",
- "translation": "Missing required channel property: type."
+ "translation": "La propriété de canal requise est manquante: type."
},
{
"id": "app.import.validate_post_import_data.channel_missing.error",
- "translation": "Missing required Post property: Channel."
+ "translation": "La propriété de message requise est manquante: Channel."
},
{
"id": "app.import.validate_post_import_data.create_at_missing.error",
- "translation": "Missing required Post property: create_at."
+ "translation": "La propriété de message requise est manquante: create_at."
},
{
"id": "app.import.validate_post_import_data.create_at_zero.error",
- "translation": "Post CreateAt must not be zero if it is provided."
+ "translation": "La propriété CreateAt du message ne peut pas être zéro si elle est spécifiée."
},
{
"id": "app.import.validate_post_import_data.message_length.error",
- "translation": "Post Message property is longer than the maximum permitted length."
+ "translation": "La propriété Message du message est plus longue que la longueur maximale autorisée."
},
{
"id": "app.import.validate_post_import_data.message_missing.error",
- "translation": "Missing required Post property: Message."
+ "translation": "La propriété de message requise est manquante: Message."
},
{
"id": "app.import.validate_post_import_data.team_missing.error",
- "translation": "Missing required Post property: Team."
+ "translation": "La propriété de message requise est manquante: Team."
},
{
"id": "app.import.validate_post_import_data.user_missing.error",
- "translation": "Missing required Post property: User."
+ "translation": "La propriété de message requise est manquante: User."
},
{
"id": "app.import.validate_team_import_data.allowed_domains_length.error",
- "translation": "Team allowed_domains is too long."
+ "translation": "La propriété d'équipe allowed_domains is trop longue."
},
{
"id": "app.import.validate_team_import_data.create_at_zero.error",
- "translation": "Team create_at must not be 0 if provided."
+ "translation": "La propriété d'équipe create_at ne doit pas être 0 si ce champ est fourni."
},
{
"id": "app.import.validate_team_import_data.description_length.error",
- "translation": "Team description is too long."
+ "translation": "La description de l'équipe est trop longue."
},
{
"id": "app.import.validate_team_import_data.display_name_length.error",
- "translation": "Team display_name is not within permitted length constraints."
+ "translation": "La propriété d'équipe display_name ne respecte pas les contraintes de longueur autorisées."
},
{
"id": "app.import.validate_team_import_data.display_name_missing.error",
- "translation": "Missing required team property: display_name"
+ "translation": "La propriété d'équipe requise est manquante: display_name."
},
{
"id": "app.import.validate_team_import_data.name_characters.error",
- "translation": "Team name contains invalid characters."
+ "translation": "Le nom de l'équipe contient des caractères invalides."
},
{
"id": "app.import.validate_team_import_data.name_length.error",
- "translation": "Team name is too long."
+ "translation": "Le nom de l'équipe est trop long."
},
{
"id": "app.import.validate_team_import_data.name_missing.error",
- "translation": "Missing required team property: name."
+ "translation": "La propriété d'équipe requise est manquante: name."
},
{
"id": "app.import.validate_team_import_data.name_reserved.error",
- "translation": "Team name contains reserved word."
+ "translation": "Le nom de l'équipe contient des words réservés."
},
{
"id": "app.import.validate_team_import_data.type_invalid.error",
- "translation": "Team type is not valid."
+ "translation": "Le type d'équipe est invalide."
},
{
"id": "app.import.validate_team_import_data.type_missing.error",
- "translation": "Missing required team property: type"
+ "translation": "La propriété d'équipe requise est manquante: type."
},
{
"id": "app.import.validate_user_channels_import_data.channel_name_missing.error",
- "translation": "Channel name missing from User's Channel Membership."
+ "translation": "Le nom du canal est manquant de la liste des canaux de l'utilisateur."
},
{
"id": "app.import.validate_user_channels_import_data.invalid_notify_props_desktop.error",
- "translation": "Invalid Desktop NotifyProps for User's Channel Membership."
+ "translation": "La propriété Desktop NotifyProps de la liste des canaux de l'utilisateur est invalide."
},
{
"id": "app.import.validate_user_channels_import_data.invalid_notify_props_mark_unread.error",
- "translation": "Invalid MarkUnread NotifyProps for User's Channel Membership."
+ "translation": "La propriété MarkUnread NotifyProps de la liste des canaux de l'utilisateur est invalide."
},
{
"id": "app.import.validate_user_channels_import_data.invalid_roles.error",
- "translation": "Invalid roles for User's Channel Membership."
+ "translation": "Rôles invalides pour la liste des canaux de l'utilisateur."
},
{
"id": "app.import.validate_user_import_data.auth_data_length.error",
- "translation": "User AuthData is too long."
+ "translation": "Les données d'authentification utilisateur sont trop longues."
},
{
"id": "app.import.validate_user_import_data.auth_service_length.error",
- "translation": "User AuthService should not be empty if it is provided."
+ "translation": "La propriété User AuthService ne doit pas être vide si celle-ci est fournie."
},
{
"id": "app.import.validate_user_import_data.email_length.error",
- "translation": "User email has an invalid length."
+ "translation": "L'adresse e-mail de l'utilisateur a une longueur invalide."
},
{
"id": "app.import.validate_user_import_data.email_missing.error",
- "translation": "Missing required user property: email."
+ "translation": "La propriété de message requise est manquante: email."
},
{
"id": "app.import.validate_user_import_data.first_name_length.error",
- "translation": "User First Name is too long."
+ "translation": "Le prénom de l'utilisateur est trop long."
},
{
"id": "app.import.validate_user_import_data.last_name_length.error",
- "translation": "User Last Name is too long."
+ "translation": "Le nom de famille de l'utilisateur est trop long."
},
{
"id": "app.import.validate_user_import_data.nickname_length.error",
- "translation": "User nickname is too long."
+ "translation": "Le surnom de l'utilisateur est trop long."
},
{
"id": "app.import.validate_user_import_data.position_length.error",
- "translation": "User Position is too long."
+ "translation": "Le rôle de l'utilisateur est trop long."
},
{
"id": "app.import.validate_user_import_data.roles_invalid.error",
- "translation": "User roles are not valid."
+ "translation": "Les rôles de l'utilisateur sont invalides."
},
{
"id": "app.import.validate_user_import_data.username_invalid.error",
- "translation": "Username is not valid."
+ "translation": "Le nom d’utilisateur est invalide."
},
{
"id": "app.import.validate_user_import_data.username_missing.error",
- "translation": "Missing require user property: username."
+ "translation": "La propriété d'utilisateur requise est manquante: username."
},
{
"id": "app.import.validate_user_teams_import_data.invalid_roles.error",
- "translation": "Invalid roles for User's Team Membership."
+ "translation": "Rôles invalides pour la liste des canaux de l'utilisateur."
},
{
"id": "app.import.validate_user_teams_import_data.team_name_missing.error",
- "translation": "Team name missing from User's Team Membership."
+ "translation": "Le nom d'équipe est manquant de la liste des canaux de l'utilisateur."
},
{
"id": "authentication.permissions.create_group_channel.description",
- "translation": "Ability to create new group message channels"
+ "translation": "Possibilité de créer de nouveaux canaux pour les messages de groupe."
},
{
"id": "authentication.permissions.create_group_channel.name",
- "translation": "Create Group Message"
+ "translation": "Créer un message de groupe"
},
{
"id": "authentication.permissions.create_team_roles.description",
- "translation": "Ability to create new teams"
+ "translation": "Possibilité de créer de nouvelles équipes"
},
{
"id": "authentication.permissions.create_team_roles.name",
- "translation": "Create Teams"
+ "translation": "Créer des équipes"
},
{
"id": "authentication.permissions.manage_team_roles.description",
- "translation": "Ability to change the roles of a team member"
+ "translation": "Possibilité de changer les rôles d'un membre d'une équipe"
},
{
"id": "authentication.permissions.manage_team_roles.name",
- "translation": "Manage Team Roles"
+ "translation": "Gérer les rôles d'équipe"
},
{
"id": "authentication.permissions.team_invite_user.description",
@@ -3589,7 +3593,7 @@
},
{
"id": "model.channel.is_valid.header.app_error",
- "translation": "En-tête invalide"
+ "translation": "Entête invalide"
},
{
"id": "model.channel.is_valid.id.app_error",
@@ -3617,7 +3621,7 @@
},
{
"id": "model.channel_member.is_valid.email_value.app_error",
- "translation": "Invalid email notification value"
+ "translation": "Valeur de la notification e-mail invalide"
},
{
"id": "model.channel_member.is_valid.notify_level.app_error",
@@ -3625,7 +3629,7 @@
},
{
"id": "model.channel_member.is_valid.push_level.app_error",
- "translation": "Invalid push notification level"
+ "translation": "Niveau de notification push invalide"
},
{
"id": "model.channel_member.is_valid.role.app_error",
@@ -3661,7 +3665,7 @@
},
{
"id": "model.client.read_file.app_error",
- "translation": "Nous avons rencontré une erreur lors de la recherche des profils utilisateurs"
+ "translation": "Une erreur s'est produite lors de la lecture du fichier"
},
{
"id": "model.client.set_profile_user.no_file.app_error",
@@ -3669,7 +3673,7 @@
},
{
"id": "model.client.set_profile_user.writer.app_error",
- "translation": "Impossible d'écrire la demande"
+ "translation": "Impossible d'écrire la requête"
},
{
"id": "model.command.is_valid.create_at.app_error",
@@ -3745,15 +3749,15 @@
},
{
"id": "model.config.is_valid.cluster_email_batching.app_error",
- "translation": "Impossible d'activer l'envoi d'e-mails groupés lorsque le clustering est activé"
+ "translation": "Impossible d'activer l'envoi d'e-mails par lot lorsque le clustering est activé"
},
{
"id": "model.config.is_valid.email_batching_buffer_size.app_error",
- "translation": "Taille du buffer d'envoi d'e-mails groupés invalide. Doit être 0 ou un nombre positif."
+ "translation": "Taille du buffer d'envoi d'e-mails par lot invalide. Doit être 0 ou un nombre positif."
},
{
"id": "model.config.is_valid.email_batching_interval.app_error",
- "translation": "Intervalle d'envoi d'e-mails groupés invalide pour les réglages de courriels. Doit être égal ou supérieur à 30 secondes."
+ "translation": "Intervalle d'envoi d'e-mails par lot invalide pour les réglages de courriels. Doit être égal ou supérieur à 30 secondes."
},
{
"id": "model.config.is_valid.email_reset_salt.app_error",
@@ -3949,7 +3953,7 @@
},
{
"id": "model.config.is_valid.site_url_email_batching.app_error",
- "translation": "Impossible d'activer l'envoi d'e-mails groupés si SiteURL n'est pas défini."
+ "translation": "Impossible d'activer l'envoi d'e-mails par lot si SiteURL n'est pas défini."
},
{
"id": "model.config.is_valid.sitename_length.app_error",
@@ -3973,7 +3977,7 @@
},
{
"id": "model.config.is_valid.time_between_user_typing.app_error",
- "translation": "Time between user typing updates should not be set to less than 1000 milliseconds."
+ "translation": "Le temps entre chaque utilisateur tapant une mise à jour ne doit pas être inférieur à 1000 millisecondes."
},
{
"id": "model.config.is_valid.webrtc_gateway_admin_secret.app_error",
@@ -4353,7 +4357,7 @@
},
{
"id": "model.user.is_valid.position.app_error",
- "translation": "Poste invalide : ne doit pas faire plus de 35 caractères."
+ "translation": "Rôle invalide : ne doit pas faire plus de 35 caractères."
},
{
"id": "model.user.is_valid.pwd.app_error",
@@ -4593,7 +4597,7 @@
},
{
"id": "store.sql_channel.analytics_deleted_type_count.app_error",
- "translation": "Nous n'avons pas pu obtenir le nombre de type de canaux"
+ "translation": "Impossible de supprimer le nombre de type de canaux"
},
{
"id": "store.sql_channel.analytics_type_count.app_error",
@@ -4601,15 +4605,15 @@
},
{
"id": "store.sql_channel.check_open_channel_permissions.app_error",
- "translation": "Nous n'avons pas pu vérifier les droits"
+ "translation": "Impossible de vérifier les permissions"
},
{
"id": "store.sql_channel.check_permissions.app_error",
- "translation": "Nous n'avons pas pu vérifier les droits"
+ "translation": "Impossible de vérifier les permissions"
},
{
"id": "store.sql_channel.check_permissions_by_name.app_error",
- "translation": "Nous n'avons pas pu vérifier les droits"
+ "translation": "Impossible de vérifier les permissions"
},
{
"id": "store.sql_channel.delete.channel.app_error",
@@ -4653,11 +4657,11 @@
},
{
"id": "store.sql_channel.get_deleted_by_name.existing.app_error",
- "translation": "Nous n'avons pas pu trouver le canal existant"
+ "translation": "Impossible de trouver le canal supprimé existant"
},
{
"id": "store.sql_channel.get_deleted_by_name.missing.app_error",
- "translation": "No deleted channel exists with that name"
+ "translation": "Aucun nom de canal supprimé portant ce nom existe"
},
{
"id": "store.sql_channel.get_extra_members.app_error",
@@ -4701,7 +4705,7 @@
},
{
"id": "store.sql_channel.permanent_delete.app_error",
- "translation": "Nous n'avons pas pu supprimer le canal"
+ "translation": "Impossible de supprimer le canal"
},
{
"id": "store.sql_channel.permanent_delete_by_team.app_error",
@@ -4737,7 +4741,7 @@
},
{
"id": "store.sql_channel.save_channel.exists.app_error",
- "translation": "A channel with that name already exists on the same team"
+ "translation": "Un canal portant ce nom existe déjà dans la même équipe"
},
{
"id": "store.sql_channel.save_channel.limit.app_error",
@@ -5053,7 +5057,7 @@
},
{
"id": "store.sql_post.get_posts_created_att.app_error",
- "translation": "Nous n'avons pas pu obtenir les messages pour le canal"
+ "translation": "Impossible de récupérer les messages du canal"
},
{
"id": "store.sql_post.get_posts_since.app_error",
@@ -5065,7 +5069,7 @@
},
{
"id": "store.sql_post.overwrite.app_error",
- "translation": "Nous n'avons pas pu supprimer le message"
+ "translation": "Impossible de remplacer le message"
},
{
"id": "store.sql_post.permanent_delete.app_error",
@@ -5077,7 +5081,7 @@
},
{
"id": "store.sql_post.permanent_delete_by_channel.app_error",
- "translation": "Nous n'avons pas pu supprimer le canal"
+ "translation": "Impossible de supprimer les messages par canal"
},
{
"id": "store.sql_post.permanent_delete_by_user.app_error",
@@ -5097,7 +5101,7 @@
},
{
"id": "store.sql_post.search.warn",
- "translation": "Query error searching posts: %v"
+ "translation": "Erreur de requête lors de la recherche de messages: %v"
},
{
"id": "store.sql_post.update.app_error",
@@ -5389,7 +5393,7 @@
},
{
"id": "store.sql_team.save.domain_exists.app_error",
- "translation": "Une équipe avec le même domaine existe déjà"
+ "translation": "Une équipe portant le même nom existe déjà"
},
{
"id": "store.sql_team.save.existing.app_error",
@@ -5425,11 +5429,11 @@
},
{
"id": "store.sql_user.analytics_get_inactive_users_count.app_error",
- "translation": "Nous n'avons pas pu compter les utilisateurs"
+ "translation": "Impossible de compter les utilisateurs inactifs"
},
{
"id": "store.sql_user.analytics_get_system_admin_count.app_error",
- "translation": "We couldn't get the system admin count"
+ "translation": "Impossible de récupérer le nombre d'administrateurs systèmes"
},
{
"id": "store.sql_user.analytics_unique_user_count.app_error",
@@ -5673,7 +5677,7 @@
},
{
"id": "store.sql_webhooks.update_incoming.app_error",
- "translation": "Nous n'avons pas pu enregistrer le IncomongWebhook"
+ "translation": "Impossible de mettre à jour le Webhook entrant"
},
{
"id": "store.sql_webhooks.update_outgoing.app_error",
@@ -5705,15 +5709,15 @@
},
{
"id": "utils.config.supported_client_locale.app_error",
- "translation": "Unable to load mattermost configuration file: DefaultClientLocale must be one of the supported locales"
+ "translation": "Impossible de charger le fichier de configuration de Mattermost: DefaultClientLocale doit être l'un des paramètres régionaux pris en charge"
},
{
"id": "utils.config.supported_server_locale.app_error",
- "translation": "Unable to load mattermost configuration file: DefaultServerLocale must be one of the supported locales"
+ "translation": "Impossible de charger le fichier de configuration de Mattermost: DefaultServerLocale doit être l'un des paramètres régionaux pris en charge"
},
{
"id": "utils.config.validate_locale.app_error",
- "translation": "Unable to load mattermost configuration file: AvailableLocales must include DefaultClientLocale"
+ "translation": "Impossible de charger le fichier de configuration de Mattermost: AvailableLocales doit inclure DefaultClientLocale"
},
{
"id": "utils.diagnostic.analytics_not_found.app_error",
@@ -5873,7 +5877,7 @@
},
{
"id": "web.incoming_webhook.permissions.app_error",
- "translation": "Autorisations pour le canal insuffisantes"
+ "translation": "Permissions insuffisantes pour ce canal"
},
{
"id": "web.incoming_webhook.text.app_error",
diff --git a/i18n/ja.json b/i18n/ja.json
index 3d63a370c..b1041b33f 100644
--- a/i18n/ja.json
+++ b/i18n/ja.json
@@ -1516,6 +1516,10 @@
"translation": "投稿APIルートを初期化しています"
},
{
+ "id": "api.post.link_preview_disabled.app_error",
+ "translation": "リンクプレビュー機能はシステム管理者によって無効にされています。"
+ },
+ {
"id": "api.post.make_direct_channel_visible.get_2_members.error",
"translation": "ダイレクトチャンネルの2人のメンバーを取得できませんでした channel_id={{.ChannelId}}"
},
diff --git a/i18n/ko.json b/i18n/ko.json
index 89aebcce3..12a75dfb2 100644
--- a/i18n/ko.json
+++ b/i18n/ko.json
@@ -1516,6 +1516,10 @@
"translation": "post API 경로 초기화 중"
},
{
+ "id": "api.post.link_preview_disabled.app_error",
+ "translation": "시스템 관리자가 개인 링크들 저장을 할 수 없도록 했습니다."
+ },
+ {
"id": "api.post.make_direct_channel_visible.get_2_members.error",
"translation": "다이렉트 채널의 두명의 구성원을 가져올 수 없습니다. channel_id=%v"
},
diff --git a/i18n/nl.json b/i18n/nl.json
index d42bfb103..54875f8f1 100644
--- a/i18n/nl.json
+++ b/i18n/nl.json
@@ -1516,6 +1516,10 @@
"translation": "Initialisatie van de berichten API routes"
},
{
+ "id": "api.post.link_preview_disabled.app_error",
+ "translation": "Publieke links zijn uitgeschakeld door de systeembeheerder"
+ },
+ {
"id": "api.post.make_direct_channel_visible.get_2_members.error",
"translation": "Het is niet gelukt om de 2 deelnemers op te halen van een direct kanaal. channel_id=%v"
},
diff --git a/i18n/pt-BR.json b/i18n/pt-BR.json
index 99992efc6..a5377897b 100644
--- a/i18n/pt-BR.json
+++ b/i18n/pt-BR.json
@@ -221,11 +221,11 @@
},
{
"id": "api.channel.create_group.bad_size.app_error",
- "translation": "Group message channels must contain at least 3 and no more than 8 users"
+ "translation": "Os canais de grupo de mensagem deve conter pelo menos 3 e não mais que 8 usuários"
},
{
"id": "api.channel.create_group.bad_user.app_error",
- "translation": "One of the provided users does not exist"
+ "translation": "Um dos usuários fornecidos não existe"
},
{
"id": "api.channel.delete_channel.archived",
@@ -901,7 +901,7 @@
},
{
"id": "api.email_batching.render_batched_post.group_message",
- "translation": "Group Message"
+ "translation": "Grupo de Mensagem"
},
{
"id": "api.email_batching.render_batched_post.sender.app_error",
@@ -1516,6 +1516,10 @@
"translation": "Inicializando as rotas de API post"
},
{
+ "id": "api.post.link_preview_disabled.app_error",
+ "translation": "Pré-visualizações de links foram desabilitados pelo administrador do sistema."
+ },
+ {
"id": "api.post.make_direct_channel_visible.get_2_members.error",
"translation": "Falha ao obter 2 membros para o canal direto channel_id={{.ChannelId}}"
},
@@ -1817,11 +1821,11 @@
},
{
"id": "api.slackimport.slack_add_users.missing_email_address",
- "translation": "User {{.Username}} does not have an email address in the Slack export. Using {{.Email}} as a placeholder. The user should update their email address once logged in to the system.\r\n"
+ "translation": "O usuário {{.Username}} não possui um endereço de email na exportação do Slack. Utilizando o {{.Email}} no lugar. O usuário deveria atualizar o seu endereço de email assim que se logar no sistema.\r\n"
},
{
"id": "api.slackimport.slack_add_users.missing_email_address.warn",
- "translation": "User {{.Username}} does not have an email address in the Slack export. Using {{.Email}} as a placeholder. The user should update their email address once logged in to the system."
+ "translation": "O usuário {{.Username}} não possui um endereço de email na exportação do Slack. Utilizando o {{.Email}} no lugar. O usuário deveria atualizar o seu endereço de email assim que se logar no sistema."
},
{
"id": "api.slackimport.slack_add_users.unable_import",
@@ -2037,7 +2041,7 @@
},
{
"id": "api.templates.channel_name.group",
- "translation": "Group Message"
+ "translation": "Grupo de mensagem"
},
{
"id": "api.templates.email_change_body.info",
@@ -2173,7 +2177,7 @@
},
{
"id": "api.templates.post_subject_in_group_message",
- "translation": "{{.SubjectText}} de {{.SenderDisplayName}} em {{.Day}} {{.Month}}, {{.Year}}"
+ "translation": "Novo grupo de mensagem de {{.SenderDisplayName}} em {{.Day}} {{.Month}}, {{.Year}}"
},
{
"id": "api.templates.reset_body.button",
@@ -3081,11 +3085,11 @@
},
{
"id": "authentication.permissions.create_group_channel.description",
- "translation": "Ability to create new group message channels"
+ "translation": "Capacidade de criar novo canal de grupo de mensagem"
},
{
"id": "authentication.permissions.create_group_channel.name",
- "translation": "Create Group Message"
+ "translation": "Criar grupo de mensagem"
},
{
"id": "authentication.permissions.create_team_roles.description",
@@ -5097,7 +5101,7 @@
},
{
"id": "store.sql_post.search.warn",
- "translation": "Query error searching posts: %v"
+ "translation": "Error na query de procurar os posts: %v"
},
{
"id": "store.sql_post.update.app_error",
@@ -5705,15 +5709,15 @@
},
{
"id": "utils.config.supported_client_locale.app_error",
- "translation": "Unable to load mattermost configuration file: DefaultClientLocale must be one of the supported locales"
+ "translation": "Não foi possível carregar o arquivo de configuração do mattermost: O DefaultClientLocale deve ser um dos idiomas suportados"
},
{
"id": "utils.config.supported_server_locale.app_error",
- "translation": "Unable to load mattermost configuration file: DefaultServerLocale must be one of the supported locales"
+ "translation": "Não foi possível carregar o arquivo de configuração do mattermost: O DefaultServerLocale deve ser um idioma suportado"
},
{
"id": "utils.config.validate_locale.app_error",
- "translation": "Unable to load mattermost configuration file: AvailableLocales must include DefaultClientLocale"
+ "translation": "Não foi possível carregar o arquivo de configuração do mattermost: AvailableLocales deve ser incluir o DefaultClientLocale"
},
{
"id": "utils.diagnostic.analytics_not_found.app_error",
diff --git a/i18n/ru.json b/i18n/ru.json
index 0497f4c22..e229da173 100644
--- a/i18n/ru.json
+++ b/i18n/ru.json
@@ -1516,6 +1516,10 @@
"translation": "Инициализация API отправки"
},
{
+ "id": "api.post.link_preview_disabled.app_error",
+ "translation": "Предпросмотр ссылок был запрещён системным администратором."
+ },
+ {
"id": "api.post.make_direct_channel_visible.get_2_members.error",
"translation": "Не удалось получить 2 участников для канала личных сообщений channel_id={{.ChannelId}}"
},
diff --git a/i18n/zh_CN.json b/i18n/zh-CN.json
index cef1f7e9d..efa7fdc2f 100644
--- a/i18n/zh_CN.json
+++ b/i18n/zh-CN.json
@@ -1516,6 +1516,10 @@
"translation": "正在初始化发文 API 路由"
},
{
+ "id": "api.post.link_preview_disabled.app_error",
+ "translation": "链接预览已被系统管理员禁用。"
+ },
+ {
"id": "api.post.make_direct_channel_visible.get_2_members.error",
"translation": "获取私聊频道的2个用户失败 channel_id={{.ChannelId}}"
},
diff --git a/i18n/zh_TW.json b/i18n/zh-TW.json
index 7eeb068c3..39fe17401 100644
--- a/i18n/zh_TW.json
+++ b/i18n/zh-TW.json
@@ -1516,6 +1516,10 @@
"translation": "正在初始化貼文 API 路徑"
},
{
+ "id": "api.post.link_preview_disabled.app_error",
+ "translation": "連結預覽已被系統管理員停用"
+ },
+ {
"id": "api.post.make_direct_channel_visible.get_2_members.error",
"translation": "取得直接訊息頻道的兩位成員失敗 channel_id={{.ChannelId}}"
},
diff --git a/model/command_response.go b/model/command_response.go
index bbb70418e..f69772353 100644
--- a/model/command_response.go
+++ b/model/command_response.go
@@ -5,6 +5,7 @@ package model
import (
"encoding/json"
+ "fmt"
"io"
)
@@ -14,12 +15,12 @@ const (
)
type CommandResponse struct {
- ResponseType string `json:"response_type"`
- Text string `json:"text"`
- Username string `json:"username"`
- IconURL string `json:"icon_url"`
- GotoLocation string `json:"goto_location"`
- Attachments interface{} `json:"attachments"`
+ ResponseType string `json:"response_type"`
+ Text string `json:"text"`
+ Username string `json:"username"`
+ IconURL string `json:"icon_url"`
+ GotoLocation string `json:"goto_location"`
+ Attachments []*SlackAttachment `json:"attachments"`
}
func (o *CommandResponse) ToJson() string {
@@ -34,10 +35,19 @@ func (o *CommandResponse) ToJson() string {
func CommandResponseFromJson(data io.Reader) *CommandResponse {
decoder := json.NewDecoder(data)
var o CommandResponse
- err := decoder.Decode(&o)
- if err == nil {
- return &o
- } else {
+
+ if err := decoder.Decode(&o); err != nil {
return nil
}
+
+ // Ensure attachment fields are stored as strings
+ for _, attachment := range o.Attachments {
+ for _, field := range attachment.Fields {
+ if field.Value != nil {
+ field.Value = fmt.Sprintf("%v", field.Value)
+ }
+ }
+ }
+
+ return &o
}
diff --git a/model/command_response_test.go b/model/command_response_test.go
index 7aa3e984b..131d87789 100644
--- a/model/command_response_test.go
+++ b/model/command_response_test.go
@@ -17,3 +17,68 @@ func TestCommandResponseJson(t *testing.T) {
t.Fatal("Ids do not match")
}
}
+
+func TestCommandResponseFromJson(t *testing.T) {
+ json := `{
+ "response_type": "ephemeral",
+ "text": "response text",
+ "username": "response username",
+ "icon_url": "response icon url",
+ "goto_location": "response goto location",
+ "attachments": [{
+ "text": "attachment 1 text",
+ "pretext": "attachment 1 pretext"
+ },{
+ "text": "attachment 2 text",
+ "fields": [{
+ "title": "field 1",
+ "value": "value 1",
+ "short": true
+ },{
+ "title": "field 2",
+ "value": [],
+ "short": false
+ }]
+ }]
+ }`
+
+ response := CommandResponseFromJson(strings.NewReader(json))
+
+ if response == nil {
+ t.Fatal("should've received non-nil CommandResponse")
+ }
+
+ if response.ResponseType != "ephemeral" {
+ t.Fatal("should've received correct response type")
+ } else if response.Text != "response text" {
+ t.Fatal("should've received correct response text")
+ } else if response.Username != "response username" {
+ t.Fatal("should've received correct response username")
+ } else if response.IconURL != "response icon url" {
+ t.Fatal("should've received correct response icon url")
+ } else if response.GotoLocation != "response goto location" {
+ t.Fatal("should've received correct response goto location")
+ }
+
+ attachments := response.Attachments
+ if len(attachments) != 2 {
+ t.Fatal("should've received 2 attachments")
+ } else if attachments[0].Text != "attachment 1 text" {
+ t.Fatal("should've received correct first attachment text")
+ } else if attachments[0].Pretext != "attachment 1 pretext" {
+ t.Fatal("should've received correct first attachment pretext")
+ } else if attachments[1].Text != "attachment 2 text" {
+ t.Fatal("should've received correct second attachment text")
+ }
+
+ fields := attachments[1].Fields
+ if len(fields) != 2 {
+ t.Fatal("should've received 2 fields")
+ } else if fields[0].Value.(string) != "value 1" {
+ t.Fatal("should've received correct first attachment value")
+ } else if _, ok := fields[1].Value.(string); !ok {
+ t.Fatal("should've received second attachment value parsed as a string")
+ } else if fields[1].Value.(string) != "[]" {
+ t.Fatal("should've received correct second attachment value")
+ }
+}
diff --git a/model/incoming_webhook.go b/model/incoming_webhook.go
index 72fa3e54c..2cc26cbca 100644
--- a/model/incoming_webhook.go
+++ b/model/incoming_webhook.go
@@ -29,13 +29,13 @@ type IncomingWebhook struct {
}
type IncomingWebhookRequest struct {
- Text string `json:"text"`
- Username string `json:"username"`
- IconURL string `json:"icon_url"`
- ChannelName string `json:"channel"`
- Props StringInterface `json:"props"`
- Attachments interface{} `json:"attachments"`
- Type string `json:"type"`
+ Text string `json:"text"`
+ Username string `json:"username"`
+ IconURL string `json:"icon_url"`
+ ChannelName string `json:"channel"`
+ Props StringInterface `json:"props"`
+ Attachments []*SlackAttachment `json:"attachments"`
+ Type string `json:"type"`
}
func (o *IncomingWebhook) ToJson() string {
@@ -212,31 +212,15 @@ func expandAnnouncement(text string) string {
func expandAnnouncements(i *IncomingWebhookRequest) {
i.Text = expandAnnouncement(i.Text)
- if i.Attachments != nil {
- attachments := i.Attachments.([]interface{})
- for _, attachment := range attachments {
- a := attachment.(map[string]interface{})
+ for _, attachment := range i.Attachments {
+ attachment.Pretext = expandAnnouncement(attachment.Pretext)
+ attachment.Text = expandAnnouncement(attachment.Text)
+ attachment.Title = expandAnnouncement(attachment.Title)
- if a["pretext"] != nil {
- a["pretext"] = expandAnnouncement(a["pretext"].(string))
- }
-
- if a["text"] != nil {
- a["text"] = expandAnnouncement(a["text"].(string))
- }
-
- if a["title"] != nil {
- a["title"] = expandAnnouncement(a["title"].(string))
- }
-
- if a["fields"] != nil {
- fields := a["fields"].([]interface{})
- for _, field := range fields {
- f := field.(map[string]interface{})
- if f["value"] != nil {
- f["value"] = expandAnnouncement(fmt.Sprintf("%v", f["value"]))
- }
- }
+ for _, field := range attachment.Fields {
+ if field.Value != nil {
+ // Ensure the value is set to a string if it is set
+ field.Value = expandAnnouncement(fmt.Sprintf("%v", field.Value))
}
}
}
diff --git a/model/incoming_webhook_test.go b/model/incoming_webhook_test.go
index 8246b6c0a..46e5b6743 100644
--- a/model/incoming_webhook_test.go
+++ b/model/incoming_webhook_test.go
@@ -142,21 +142,20 @@ func TestIncomingWebhookRequestFromJson_Announcements(t *testing.T) {
t.Fatal("IncomingWebhookRequest should not be nil")
}
- attachments := iwr.Attachments.([]interface{})
- attachment := attachments[0].(map[string]interface{})
- if attachment["pretext"] != expected {
- t.Fatalf("Sample attachment pretext should be: %s, got: %s", expected, attachment["pretext"])
+ attachment := iwr.Attachments[0]
+ if attachment.Pretext != expected {
+ t.Fatalf("Sample attachment pretext should be:%s, got: %s", expected, attachment.Pretext)
}
- if attachment["text"] != expected {
- t.Fatalf("Sample attachment text should be: %s, got: %s", expected, attachment["text"])
+ if attachment.Text != expected {
+ t.Fatalf("Sample attachment text should be: %s, got: %s", expected, attachment.Text)
}
- if attachment["title"] != expected {
- t.Fatalf("Sample attachment title should be: %s, got: %s", expected, attachment["title"])
+ if attachment.Title != expected {
+ t.Fatalf("Sample attachment title should be: %s, got: %s", expected, attachment.Title)
}
- fields := attachment["fields"].([]interface{})
- field := fields[0].(map[string]interface{})
- if field["value"] != expected {
- t.Fatalf("Sample attachment field value should be: %s, got: %s", expected, field["value"])
+
+ field := attachment.Fields[0]
+ if field.Value != expected {
+ t.Fatalf("Sample attachment field value should be: %s, got: %s", expected, field.Value)
}
}
@@ -224,10 +223,10 @@ func TestIncomingWebhookRequestFromJson(t *testing.T) {
if iwr.Text != expected {
t.Fatalf("Sample %d text should be: %s, got: %s", i, expected, iwr.Text)
}
- attachments := iwr.Attachments.([]interface{})
- attachment := attachments[0].(map[string]interface{})
- if attachment["text"] != expected {
- t.Fatalf("Sample %d attachment text should be: %s, got: %s", i, expected, attachment["text"])
+
+ attachment := iwr.Attachments[0]
+ if attachment.Text != expected {
+ t.Fatalf("Sample %d attachment text should be: %s, got: %s", i, expected, attachment.Text)
}
}
}
diff --git a/model/slack_attachment.go b/model/slack_attachment.go
new file mode 100644
index 000000000..e1639f2af
--- /dev/null
+++ b/model/slack_attachment.go
@@ -0,0 +1,29 @@
+// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package model
+
+type SlackAttachment struct {
+ Id int64 `json:"id"`
+ Fallback string `json:"fallback"`
+ Color string `json:"color"`
+ Pretext string `json:"pretext"`
+ AuthorName string `json:"author_name"`
+ AuthorLink string `json:"author_link"`
+ AuthorIcon string `json:"author_icon"`
+ Title string `json:"title"`
+ TitleLink string `json:"title_link"`
+ Text string `json:"text"`
+ Fields []*SlackAttachmentField `json:"fields"`
+ ImageURL string `json:"image_url"`
+ ThumbURL string `json:"thumb_url"`
+ Footer string `json:"footer"`
+ FooterIcon string `json:"footer_icon"`
+ Timestamp interface{} `json:"ts"` // This is either a string or an int64
+}
+
+type SlackAttachmentField struct {
+ Title string `json:"title"`
+ Value interface{} `json:"value"`
+ Short bool `json:"short"`
+}
diff --git a/web/web_test.go b/web/web_test.go
index dd1dcf19c..8db0eb91c 100644
--- a/web/web_test.go
+++ b/web/web_test.go
@@ -211,7 +211,7 @@ func TestIncomingWebhook(t *testing.T) {
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = ApiClient.Must(ApiClient.CreateTeam(team)).Data.(*model.Team)
- app.JoinUserToTeam(team, user)
+ app.JoinUserToTeam(team, user, utils.GetSiteURL())
app.UpdateUserRoles(user.Id, model.ROLE_SYSTEM_ADMIN.Id)
ApiClient.SetTeamId(team.Id)
diff --git a/webapp/actions/channel_actions.jsx b/webapp/actions/channel_actions.jsx
index 5d3a9db35..acbc943cf 100644
--- a/webapp/actions/channel_actions.jsx
+++ b/webapp/actions/channel_actions.jsx
@@ -9,14 +9,14 @@ import ChannelStore from 'stores/channel_store.jsx';
import * as ChannelUtils from 'utils/channel_utils.jsx';
import PreferenceStore from 'stores/preference_store.jsx';
-import {loadProfilesForSidebar} from 'actions/user_actions.jsx';
+import {loadProfilesForSidebar, loadNewDMIfNeeded, loadNewGMIfNeeded} from 'actions/user_actions.jsx';
import {trackEvent} from 'actions/diagnostics_actions.jsx';
import Client from 'client/web_client.jsx';
import * as AsyncClient from 'utils/async_client.jsx';
import * as UserAgent from 'utils/user_agent.jsx';
import * as Utils from 'utils/utils.jsx';
-import {Preferences, ActionTypes} from 'utils/constants.jsx';
+import {Constants, Preferences, ActionTypes} from 'utils/constants.jsx';
import {browserHistory} from 'react-router/es6';
@@ -283,8 +283,29 @@ export function unmarkFavorite(channelId) {
}
export function loadChannelsForCurrentUser() {
- AsyncClient.getChannels();
- AsyncClient.getMyChannelMembers();
+ AsyncClient.getChannels().then(() => {
+ AsyncClient.getMyChannelMembers().then(() => {
+ loadDMsAndGMsForUnreads();
+ });
+ });
+}
+
+export function loadDMsAndGMsForUnreads() {
+ const unreads = ChannelStore.getUnreadCounts();
+ for (const id in unreads) {
+ if (!unreads.hasOwnProperty(id)) {
+ continue;
+ }
+
+ if (unreads[id].msgs > 0 || unreads[id].mentions > 0) {
+ const channel = ChannelStore.get(id);
+ if (channel && channel.type === Constants.DM_CHANNEL) {
+ loadNewDMIfNeeded(Utils.getUserIdFromChannelName(channel));
+ } else if (channel && channel.type === Constants.GM_CHANNEL) {
+ loadNewGMIfNeeded(channel.id);
+ }
+ }
+ }
}
export function joinChannel(channel, success, error) {
diff --git a/webapp/actions/global_actions.jsx b/webapp/actions/global_actions.jsx
index e22c94294..c81478069 100644
--- a/webapp/actions/global_actions.jsx
+++ b/webapp/actions/global_actions.jsx
@@ -46,10 +46,10 @@ export function emitChannelClickEvent(channel) {
}
function switchToChannel(chan) {
const channelMember = ChannelStore.getMyMember(chan.id);
- const getMyChannelMembersPromise = AsyncClient.getChannelMember(chan.id, UserStore.getCurrentId());
+ const getMyChannelMemberPromise = AsyncClient.getChannelMember(chan.id, UserStore.getCurrentId());
const oldChannelId = ChannelStore.getCurrentId();
- getMyChannelMembersPromise.then(() => {
+ getMyChannelMemberPromise.then(() => {
AsyncClient.getChannelStats(chan.id, true);
AsyncClient.viewChannel(chan.id, oldChannelId);
loadPosts(chan.id);
diff --git a/webapp/actions/user_actions.jsx b/webapp/actions/user_actions.jsx
index 0f6ac3e9f..231b09f11 100644
--- a/webapp/actions/user_actions.jsx
+++ b/webapp/actions/user_actions.jsx
@@ -304,7 +304,7 @@ export function loadProfilesForGM() {
if (!isVisible) {
const member = ChannelStore.getMyMember(channel.id);
- if (!member || (member.mention_count === 0 && member.msg_count < member.total_msg_count)) {
+ if (!member || (member.mention_count === 0 && member.msg_count >= channel.total_msg_count)) {
continue;
}
@@ -645,7 +645,7 @@ export function checkMfa(loginId, success, error) {
loginId,
(data) => {
if (success) {
- success(data);
+ success(data && data.mfa_required === 'true');
}
},
(err) => {
diff --git a/webapp/actions/websocket_actions.jsx b/webapp/actions/websocket_actions.jsx
index 913a89221..e36d11fde 100644
--- a/webapp/actions/websocket_actions.jsx
+++ b/webapp/actions/websocket_actions.jsx
@@ -89,6 +89,26 @@ export function reconnect(includeWebSocket = true) {
ErrorStore.emitChange();
}
+let intervalId = '';
+const SYNC_INTERVAL_MILLISECONDS = 1000 * 60 * 15; // 15 minutes
+
+export function startPeriodicSync() {
+ clearInterval(intervalId);
+
+ intervalId = setInterval(
+ () => {
+ if (UserStore.getCurrentUser() != null) {
+ reconnect(false);
+ }
+ },
+ SYNC_INTERVAL_MILLISECONDS
+ );
+}
+
+export function stopPeriodicSync() {
+ clearInterval(intervalId);
+}
+
function handleFirstConnect() {
ErrorStore.clearLastError();
ErrorStore.emitChange();
diff --git a/webapp/components/access_history_modal.jsx b/webapp/components/access_history_modal.jsx
index 28a2b6b8f..4e1e69e3e 100644
--- a/webapp/components/access_history_modal.jsx
+++ b/webapp/components/access_history_modal.jsx
@@ -79,6 +79,7 @@ export default class AccessHistoryModal extends React.Component {
return (
<Modal
+ dialogClassName='modal--scroll'
show={this.state.show}
onHide={this.onHide}
onExited={this.props.onHide}
diff --git a/webapp/components/activity_log_modal.jsx b/webapp/components/activity_log_modal.jsx
index cd369f742..05c09ab88 100644
--- a/webapp/components/activity_log_modal.jsx
+++ b/webapp/components/activity_log_modal.jsx
@@ -102,7 +102,7 @@ export default class ActivityLogModal extends React.Component {
if (currentSession.props.platform === 'Windows') {
devicePicture = 'fa fa-windows';
- } else if (currentSession.device_id && currentSession.device_id.indexOf('apple:') === 0) {
+ } else if (currentSession.device_id && currentSession.device_id.indexOf('apple') === 0) {
devicePicture = 'fa fa-apple';
devicePlatform = (
<FormattedMessage
@@ -110,7 +110,7 @@ export default class ActivityLogModal extends React.Component {
defaultMessage='iPhone Native App'
/>
);
- } else if (currentSession.device_id && currentSession.device_id.indexOf('android:') === 0) {
+ } else if (currentSession.device_id && currentSession.device_id.indexOf('android') === 0) {
devicePlatform = (
<FormattedMessage
id='activity_log_modal.androidNativeApp'
@@ -275,6 +275,7 @@ export default class ActivityLogModal extends React.Component {
return (
<Modal
+ dialogClassName='modal--scroll'
show={this.state.show}
onHide={this.onHide}
onExited={this.props.onHide}
diff --git a/webapp/components/admin_console/team_users.jsx b/webapp/components/admin_console/team_users.jsx
index 0874e4c8c..5bdaedf6e 100644
--- a/webapp/components/admin_console/team_users.jsx
+++ b/webapp/components/admin_console/team_users.jsx
@@ -148,16 +148,17 @@ export default class UserList extends React.Component {
}
search(term) {
+ clearTimeout(this.searchTimeoutId);
+
if (term === '') {
this.setState({search: false, users: UserStore.getProfileListInTeam(this.props.params.team)});
+ this.searchTimeoutId = '';
return;
}
const options = {};
options[UserSearchOptions.ALLOW_INACTIVE] = true;
- clearTimeout(this.searchTimeoutId);
-
const searchTimeoutId = setTimeout(
() => {
searchUsers(
diff --git a/webapp/components/channel_invite_modal.jsx b/webapp/components/channel_invite_modal.jsx
index 5deec0794..2f1a10a75 100644
--- a/webapp/components/channel_invite_modal.jsx
+++ b/webapp/components/channel_invite_modal.jsx
@@ -107,16 +107,17 @@ export default class ChannelInviteModal extends React.Component {
}
search(term) {
+ clearTimeout(this.searchTimeoutId);
+
this.term = term;
if (term === '') {
this.onChange(true);
this.setState({search: false});
+ this.searchTimeoutId = '';
return;
}
- clearTimeout(this.searchTimeoutId);
-
const searchTimeoutId = setTimeout(
() => {
searchUsers(
diff --git a/webapp/components/create_comment.jsx b/webapp/components/create_comment.jsx
index c7dbd0717..96280bbc1 100644
--- a/webapp/components/create_comment.jsx
+++ b/webapp/components/create_comment.jsx
@@ -349,7 +349,7 @@ export default class CreateComment extends React.Component {
PostStore.storeCommentDraft(this.props.rootId, draft);
// Focus on preview if needed
- this.refs.preview.refs.container.scrollIntoViewIfNeeded();
+ this.refs.preview.refs.container.scrollIntoView();
const enableAddButton = this.handleEnableAddButton(draft.message, draft.fileInfos);
diff --git a/webapp/components/error_bar.jsx b/webapp/components/error_bar.jsx
index a1981aa2a..edb929f20 100644
--- a/webapp/components/error_bar.jsx
+++ b/webapp/components/error_bar.jsx
@@ -30,7 +30,7 @@ export default class ErrorBar extends React.Component {
this.onAnalyticsChange = this.onAnalyticsChange.bind(this);
this.handleClose = this.handleClose.bind(this);
- ErrorStore.clearNotificationError();
+ ErrorStore.clearLastError();
let isSystemAdmin = false;
const user = UserStore.getCurrentUser();
diff --git a/webapp/components/login/login_controller.jsx b/webapp/components/login/login_controller.jsx
index d0aa0a5fc..01da0199f 100644
--- a/webapp/components/login/login_controller.jsx
+++ b/webapp/components/login/login_controller.jsx
@@ -131,8 +131,8 @@ export default class LoginController extends React.Component {
checkMfa(
loginId,
- (data) => {
- if (data && data.mfa_required === 'true') {
+ (requiresMfa) => {
+ if (requiresMfa) {
this.setState({showMfa: true});
} else {
this.submit(loginId, password, '');
diff --git a/webapp/components/member_list_channel.jsx b/webapp/components/member_list_channel.jsx
index 6f8a266ad..d9d28bcd0 100644
--- a/webapp/components/member_list_channel.jsx
+++ b/webapp/components/member_list_channel.jsx
@@ -91,6 +91,8 @@ export default class MemberListChannel extends React.Component {
}
search(term) {
+ clearTimeout(this.searchTimeoutId);
+
if (term === '') {
this.setState({
search: false,
@@ -99,11 +101,10 @@ export default class MemberListChannel extends React.Component {
teamMembers: Object.assign([], TeamStore.getMembersInTeam()),
channelMembers: Object.assign([], ChannelStore.getMembersInChannel())
});
+ this.searchTimeoutId = '';
return;
}
- clearTimeout(this.searchTimeoutId);
-
const searchTimeoutId = setTimeout(
() => {
searchUsers(
diff --git a/webapp/components/member_list_team.jsx b/webapp/components/member_list_team.jsx
index df17d7df2..e06d61b0a 100644
--- a/webapp/components/member_list_team.jsx
+++ b/webapp/components/member_list_team.jsx
@@ -43,7 +43,7 @@ export default class MemberListTeam extends React.Component {
}
componentDidMount() {
- UserStore.addInTeamChangeListener(this.onChange);
+ UserStore.addInTeamChangeListener(this.onTeamChange);
UserStore.addStatusesChangeListener(this.onChange);
TeamStore.addChangeListener(this.onTeamChange);
TeamStore.addStatsChangeListener(this.onStatsChange);
@@ -53,7 +53,7 @@ export default class MemberListTeam extends React.Component {
}
componentWillUnmount() {
- UserStore.removeInTeamChangeListener(this.onChange);
+ UserStore.removeInTeamChangeListener(this.onTeamChange);
UserStore.removeStatusesChangeListener(this.onChange);
TeamStore.removeChangeListener(this.onTeamChange);
TeamStore.removeStatsChangeListener(this.onStatsChange);
@@ -88,13 +88,14 @@ export default class MemberListTeam extends React.Component {
}
search(term) {
+ clearTimeout(this.searchTimeoutId);
+
if (term === '') {
this.setState({search: false, term, users: UserStore.getProfileListInTeam(), teamMembers: Object.assign([], TeamStore.getMembersInTeam())});
+ this.searchTimeoutId = '';
return;
}
- clearTimeout(this.searchTimeoutId);
-
const searchTimeoutId = setTimeout(
() => {
searchUsers(
diff --git a/webapp/components/more_channels.jsx b/webapp/components/more_channels.jsx
index d0b5f5399..10f597ad4 100644
--- a/webapp/components/more_channels.jsx
+++ b/webapp/components/more_channels.jsx
@@ -99,14 +99,15 @@ export default class MoreChannels extends React.Component {
}
search(term) {
+ clearTimeout(this.searchTimeoutId);
+
if (term === '') {
this.onChange(true);
this.setState({search: false});
+ this.searchTimeoutId = '';
return;
}
- clearTimeout(this.searchTimeoutId);
-
const searchTimeoutId = setTimeout(
() => {
searchMoreChannels(
diff --git a/webapp/components/needs_team.jsx b/webapp/components/needs_team.jsx
index f589136b5..11e75bfb7 100644
--- a/webapp/components/needs_team.jsx
+++ b/webapp/components/needs_team.jsx
@@ -15,6 +15,8 @@ import ChannelStore from 'stores/channel_store.jsx';
import PostStore from 'stores/post_store.jsx';
import * as GlobalActions from 'actions/global_actions.jsx';
import {startPeriodicStatusUpdates, stopPeriodicStatusUpdates} from 'actions/status_actions.jsx';
+import {startPeriodicSync, stopPeriodicSync} from 'actions/websocket_actions.jsx';
+
import Constants from 'utils/constants.jsx';
const TutorialSteps = Constants.TutorialSteps;
const Preferences = Constants.Preferences;
@@ -95,6 +97,7 @@ export default class NeedsTeam extends React.Component {
GlobalActions.viewLoggedIn();
startPeriodicStatusUpdates();
+ startPeriodicSync();
// Set up tracking for whether the window is active
window.isActive = true;
@@ -141,6 +144,7 @@ export default class NeedsTeam extends React.Component {
iNoBounce.disable();
}
stopPeriodicStatusUpdates();
+ stopPeriodicSync();
}
render() {
diff --git a/webapp/components/post_view/components/post.jsx b/webapp/components/post_view/components/post.jsx
index 913c2af95..fba4ce9eb 100644
--- a/webapp/components/post_view/components/post.jsx
+++ b/webapp/components/post_view/components/post.jsx
@@ -204,9 +204,7 @@ export default class Post extends React.Component {
src={PostUtils.getProfilePicSrcForPost(post, timestamp)}
/>
);
- }
-
- if (PostUtils.isSystemMessage(post)) {
+ } else if (PostUtils.isSystemMessage(post)) {
profilePic = (
<span
className='icon'
diff --git a/webapp/i18n/de.json b/webapp/i18n/de.json
index 168233d17..a1ef10c11 100644
--- a/webapp/i18n/de.json
+++ b/webapp/i18n/de.json
@@ -217,8 +217,11 @@
"admin.customization.customEmoji": "Benutzerdefinierte Emoji",
"admin.customization.enableCustomEmojiDesc": "Erlaube es Benutzern eigene Emojis für Nachrichten zu erstellen. Wenn aktiviert, können eigene Emojis durch wechseln zu einem Team, Klicken auf die drei Punkte über der Kanal-Seitenleiste und dem Auswählen von \"Eigene Emoji\" aufgerufen werden.",
"admin.customization.enableCustomEmojiTitle": "Eigene Emoji ermöglichen:",
+ "admin.customization.enableLinkPreviewsDesc": "Erlaube Benutzern eine Vorschau einer Webseite unterhalb der Nachricht anzuzeigen, sofern verfügbar. Wenn wahr, können Webseitenvorschauen über Kontoeinstellungrn > Erweitert > Vorschau auf Features der neuen Version aktiviert werden.",
+ "admin.customization.enableLinkPreviewsTitle": "Erlaube Link Vorschauen:",
"admin.customization.iosAppDownloadLinkDesc": "Einen Link zum Download der iOS App hinzufügen. Benutzer die die Seite über einen mobilen Browser aufrufen werden eine Seite mit der Option die App herunterzuladen angezeigt. Dieses Feld leer lassen um zu verhindern dass die Seite angezeigt wird.",
"admin.customization.iosAppDownloadLinkTitle": "iOS App Download Link:",
+ "admin.customization.linkPreviews": "Link Vorschauen",
"admin.customization.nativeAppLinks": "Links zu Mattermost Anwendungen",
"admin.customization.restrictCustomEmojiCreationAdmin": "Erlaube System- und Teamadministratoren eigene Emojis zu erstellen",
"admin.customization.restrictCustomEmojiCreationAll": "Erlaube jedem eigene Emoji zu erstellen",
@@ -764,6 +767,7 @@
"admin.sidebar.ldap": "AD/LDAP",
"admin.sidebar.legalAndSupport": "Rechtsabteilung und Support",
"admin.sidebar.license": "Edition und Lizenz",
+ "admin.sidebar.linkPreviews": "Link Vorschauen",
"admin.sidebar.localization": "Lokalisation",
"admin.sidebar.logging": "Protokollierung",
"admin.sidebar.login": "Anmelden",
@@ -935,8 +939,6 @@
"analytics.system.activeUsers": "Aktive Nutzer mit Beiträgen",
"analytics.system.channelTypes": "Kanal Typen",
"analytics.system.dailyActiveUsers": "Tägliche aktive Benutzer",
- "analytics.system.expiredBanner": "Die Enterprise Lizenz im am {date} abgelaufen. Sie haben 15 Tage vom genannten Datum an Zeit die Lizenz zu erneuern, bitte kontaktieren Sie <a href='mailto:commercial@mattermost.com'>commercial@mattermost.com</a>.",
- "analytics.system.expiringBanner": "Die Enterprise Lizenz wird am {date} ablaufen. Um sie zu erneuern kontaktieren Sie bitte <a href='mailto:commercial@mattermost.com'>commercial@mattermost.com</a>.",
"analytics.system.monthlyActiveUsers": "Monatliche aktive Benutzer",
"analytics.system.postTypes": "Nachrichten, Dateien und Hashtags",
"analytics.system.privateGroups": "Private Gruppen",
@@ -1287,9 +1289,9 @@
"error.not_found.title": "Seite nicht gefunden",
"error.not_supported.message": "Privates Browsing wird nicht unterstützt",
"error.not_supported.title": "Browser nicht unterstützt",
- "error_bar.expired": "Enterprise Lizenz ist abgelaufen. Sie haben 15 Tage ab Ablaufdatum um Ihre Lizenz zu erneuern. Bitte Kontaktieren Sie commercial@mattermost.com für mehr Details",
- "error_bar.expiring": "Die Enterprise Lizenz läuft ab am {date}. Um die Lizenz zu erneuern kontaktieren Sie bitte commercial@mattermost.com",
- "error_bar.past_grace": "Enterprise Lizenz ist abgelaufen, bitte kontaktieren Sie Ihren Systemadministrator für Details",
+ "error_bar.expired": "Enterprise Lizenz ist abgelaufen und einige Funktionen wurden evtl. deaktiviert. <a href='{link}' target='_blank'>Bitte erneuern.</a>",
+ "error_bar.expiring": "Enterprise Lizenz läuft ab am {Date}. <a href='{link}' target='_blank'>Bitte erneuern.</a>",
+ "error_bar.past_grace": "Enterprise Lizenz ist abgelaufen und einige Funktionen wurden evtl. deaktiviert. Bitte wenden Sie sich an den Systemadministrator für mehr Details.",
"error_bar.preview_mode": "Vorführungsmodus: E-Mail Benachrichtigungen wurden nicht konfiguriert",
"file_attachment.download": "Download",
"file_info_preview.size": "Größe ",
@@ -1448,7 +1450,7 @@
"help.messaging.write": "**Schreiben Sie Nachrichten** indem Sie das Eingabefeld am unteren Ende von Mattermost verwenden. Drücken Sie **Enter* um sie zu versenden. Verwenden Sie **Shift+Enter** um einen Zeilenumbruch einzufügen ohne die Nachricht zu senden.",
"installed_command.header": "Slash-Befehle",
"installed_commands.add": "Slash-Befehl hinzufügen",
- "installed_commands.delete.confirm": "This action permanently deletes the slash command and breaks any integrations using it. Are you sure you want to delete it?",
+ "installed_commands.delete.confirm": "Diese Aktion wird den Slash-Befehl permanent löschen und wird jede Integration, die ihn verwendet, stoppen. Sind Sie sich sicher dass sie ihn löschen möchten?",
"installed_commands.empty": "Keine Befehle gefunden",
"installed_commands.header": "Slash-Befehle",
"installed_commands.help": "Erstelle Slash-Befehle zur Verwendung in externen Integrationen. Bitte {link} für mehr Informationen ansehen.",
@@ -1456,7 +1458,7 @@
"installed_commands.search": "Suche nach Slash-Befehlen",
"installed_commands.unnamed_command": "Unbenannter Slash-Befehl",
"installed_incoming_webhooks.add": "Eingehenden Webhook hinzufügen",
- "installed_incoming_webhooks.delete.confirm": "This action permanently deletes the incoming webhook and breaks any integrations using it. Are you sure you want to delete it?",
+ "installed_incoming_webhooks.delete.confirm": "Die Aktion wird den eingehenden Webhook permanent löschen und jede Integration, die ihn verwendet, stoppen. Sind Sie sich sicher dass sie ihn löschen möchten?",
"installed_incoming_webhooks.empty": "Keine eingehende Webhooks gefunden",
"installed_incoming_webhooks.header": "Eingehende Webhooks",
"installed_incoming_webhooks.help": "Erstelle eingehende Webhook URLs zur Verwendung in externen Integrationen. Bitte {link} für mehr Informationen ansehen.",
@@ -1482,7 +1484,7 @@
"installed_oauth_apps.add": "OAuth 2.0 Applikation hinzufügen",
"installed_oauth_apps.callbackUrls": "Callback URLs (eine pro Zeile)",
"installed_oauth_apps.cancel": "Abbrechen",
- "installed_oauth_apps.delete.confirm": "This action permanently deletes the OAuth 2.0 application and breaks any integrations using it. Are you sure you want to delete it?",
+ "installed_oauth_apps.delete.confirm": "Die Aktion wird die OAuth 2.0 Applikation permanent löschen und jede Integration, die ihn verwendet, stoppen. Sind Sie sich sicher dass sie ihn löschen möchten?",
"installed_oauth_apps.description": "Beschreibung",
"installed_oauth_apps.empty": "Keine OAuth 2.0 Applikationen gefunden",
"installed_oauth_apps.header": "OAuth 2.0 Applikationen",
@@ -1498,7 +1500,7 @@
"installed_oauth_apps.trusted.no": "Nein",
"installed_oauth_apps.trusted.yes": "Ja",
"installed_outgoing_webhooks.add": "Ausgehenden Webhook hinzufügen",
- "installed_outgoing_webhooks.delete.confirm": "This action permanently deletes the outgoing webhook and breaks any integrations using it. Are you sure you want to delete it?",
+ "installed_outgoing_webhooks.delete.confirm": "Diese Aktion wird den ausgehenden Webhook permanent löschen und und jede Integration, die ihn verwendet, stoppen. Sind Sie sich sicher dass sie ihn löschen möchten?",
"installed_outgoing_webhooks.empty": "Keine ausgehenden Webhooks gefunden",
"installed_outgoing_webhooks.header": "Ausgehende Webhooks",
"installed_outgoing_webhooks.help": "Erstelle ausgehende Webhook URLs zur Verwendung in externen Integrationen. Bitte {link} für mehr Informationen ansehen.",
@@ -1639,17 +1641,17 @@
"more_channels.title": "Weitere Kanäle",
"more_direct_channels.close": "Schließen",
"more_direct_channels.message": "Nachricht",
- "more_direct_channels.new_convo_note": "This will start a new conversation. If you’re adding a lot of people, consider creating a private group instead.",
- "more_direct_channels.new_convo_note.full": "You’ve reached the maximum number of people for this conversation. Consider creating a private group instead.",
+ "more_direct_channels.new_convo_note": "Dies wird eine neue Konversation starten, Wenn Sie viele Personen hinzufügen, könnte eine private Gruppe besser geeignet sein.",
+ "more_direct_channels.new_convo_note.full": "Sie haben die maximale Anzahl an Personen für diese Konversation erreicht. Ziehen Sie in Erwägung eine private Gruppe anzulegen.",
"more_direct_channels.title": "Direktnachricht",
"msg_typing.areTyping": "{users} und {last} tippen gerade...",
"msg_typing.isTyping": "{user} tippt...",
"msg_typing.someone": "Jemand",
- "multiselect.go": "Go",
- "multiselect.instructions": "Use up/down arrows to navigate and enter to select",
- "multiselect.numPeopleRemaining": "You can add {num, number} more {num, plural, =0 {people} one {person} other {people}}. ",
- "multiselect.numRemaining": "You can add {num, number} more",
- "multiselect.placeholder": "Search and add members",
+ "multiselect.go": "Los",
+ "multiselect.instructions": "Verwenden Sie die hoch/runter Pfeile zur Navigation und Enter zur Auswahl",
+ "multiselect.numPeopleRemaining": "Sie können {num, number} weitere {num, plural, =0 {Personen} one {Person} other {Personen}} hinzufügen. ",
+ "multiselect.numRemaining": "Sie können {num, number} weitere hinzufügen",
+ "multiselect.placeholder": "Mitglieder suchen und hinzufügen",
"navbar.addMembers": "Mitglieder hinzufügen",
"navbar.click": "Klicken Sie hier",
"navbar.delete": "Kanal löschen...",
@@ -1743,7 +1745,7 @@
"rename_channel.defaultError": " - Kann nicht für den Vorgabe-Kanal geändert werden",
"rename_channel.displayName": "Angezeigter Name",
"rename_channel.displayNameHolder": "Anzeigenamen eingeben",
- "rename_channel.handleHolder": "Dürfen nur Kleinbuchstaben oder Ziffern sein",
+ "rename_channel.handleHolder": "Kleinbuchstaben oder Ziffern",
"rename_channel.lowercase": "Dürfen nur Kleinbuchstaben oder Ziffern sein",
"rename_channel.maxLength": "Dieses Feld darf nur bis zu 22 Zeichen enthalten",
"rename_channel.required": "Dieses Feld wird erforderlich",
diff --git a/webapp/i18n/en.json b/webapp/i18n/en.json
index 36c016c23..bc30b53e7 100644
--- a/webapp/i18n/en.json
+++ b/webapp/i18n/en.json
@@ -1,14 +1,4 @@
{
- "admin.customization.enableLinkPreviewsDesc": "Enable users to display a preview of website content below the message, if available. When true, website previews can be enabled from Account Settings > Advanced > Preview pre-release features.",
- "admin.customization.enableLinkPreviewsTitle": "Enable Link Previews:",
- "admin.customization.linkPreviews": "Link Previews",
- "admin.sidebar.linkPreviews": "Link Previews",
- "multiselect.go": "Go",
- "multiselect.instructions": "Use up/down arrows to navigate and enter to select",
- "multiselect.placeholder": "Search and add members",
- "multiselect.numRemaining": "You can add {num, number} more",
- "multiselect.numPeopleRemaining": "You can add {num, number} more {num, plural, =0 {people} one {person} other {people}}. ",
- "filtered_channels_list.count": "{count} {count, plural, =0 {0 channels} one {channel} other {channels}}",
"about.close": "Close",
"about.copyright": "Copyright 2016 Mattermost, Inc. All rights reserved",
"about.database": "Database:",
@@ -227,8 +217,11 @@
"admin.customization.customEmoji": "Custom Emoji",
"admin.customization.enableCustomEmojiDesc": "Enable users to create custom emoji for use in messages. When enabled, Custom Emoji settings can be accessed by switching to a team and clicking the three dots above the channel sidebar, and selecting \"Custom Emoji\".",
"admin.customization.enableCustomEmojiTitle": "Enable Custom Emoji:",
+ "admin.customization.enableLinkPreviewsDesc": "Enable users to display a preview of website content below the message, if available. When true, website previews can be enabled from Account Settings > Advanced > Preview pre-release features.",
+ "admin.customization.enableLinkPreviewsTitle": "Enable Link Previews:",
"admin.customization.iosAppDownloadLinkDesc": "Add a link to download the iOS app. Users who access the site on a mobile web browser will be prompted with a page giving them the option to download the app. Leave this field blank to prevent the page from appearing.",
"admin.customization.iosAppDownloadLinkTitle": "iOS App Download Link:",
+ "admin.customization.linkPreviews": "Link Previews",
"admin.customization.nativeAppLinks": "Mattermost App Links",
"admin.customization.restrictCustomEmojiCreationAdmin": "Allow System and Team Admins to create custom emoji",
"admin.customization.restrictCustomEmojiCreationAll": "Allow everyone to create custom emoji",
@@ -774,6 +767,7 @@
"admin.sidebar.ldap": "AD/LDAP",
"admin.sidebar.legalAndSupport": "Legal and Support",
"admin.sidebar.license": "Edition and License",
+ "admin.sidebar.linkPreviews": "Link Previews",
"admin.sidebar.localization": "Localization",
"admin.sidebar.logging": "Logging",
"admin.sidebar.login": "Login",
diff --git a/webapp/i18n/es.json b/webapp/i18n/es.json
index 643ee0f03..902e75ba8 100644
--- a/webapp/i18n/es.json
+++ b/webapp/i18n/es.json
@@ -217,8 +217,11 @@
"admin.customization.customEmoji": "Emoticones Personalizados",
"admin.customization.enableCustomEmojiDesc": "Permite a los usuarios crear emoticones personalizados para su uso en los mensajes. Cuando se activa, Emoticones Personalizados se puede acceder a los ajustes al ingresar a un equipo y hacer clic en los tres puntos por encima del canal en la barra lateral y seleccionar \"Emoticones Personalizados\".",
"admin.customization.enableCustomEmojiTitle": "Habilitar Emoticones Personalizados:",
+ "admin.customization.enableLinkPreviewsDesc": "Habilitar a los usuarios a mostrar una vista previa del contenido del sitio web a seguido del mensaje, si está disponible. Cuando es verdadero, la vista previa de sitios web se puede activar en la Configuración de la Cuenta > Avanzado > Previsualizar características de pre-lanzamiento.",
+ "admin.customization.enableLinkPreviewsTitle": "Habilitar Vista Previa del Enlace:",
"admin.customization.iosAppDownloadLinkDesc": "Agrega un enlace para descargar la aplicación para iOS. Los usuarios que tienen acceso al sitio en un navegador de web móvil serán presentados con una página que les da la opción de descargar la aplicación. Deja este campo en blanco para evitar que la página aparezca.",
"admin.customization.iosAppDownloadLinkTitle": "Enlace de Descarga de la Aplicación para iOS:",
+ "admin.customization.linkPreviews": "Vista previa del Enlace",
"admin.customization.nativeAppLinks": "Enlaces de Mattermost App",
"admin.customization.restrictCustomEmojiCreationAdmin": "Permitir la creación de emoticones a los Administradores de Sistema y Equipo",
"admin.customization.restrictCustomEmojiCreationAll": "Permitir a todos que puedan crear emoticones personalizados",
@@ -764,6 +767,7 @@
"admin.sidebar.ldap": "AD/LDAP",
"admin.sidebar.legalAndSupport": "Legal y Soporte",
"admin.sidebar.license": "Edición y Licencia",
+ "admin.sidebar.linkPreviews": "Vista previa del Enlace",
"admin.sidebar.localization": "Idiomas",
"admin.sidebar.logging": "Registros",
"admin.sidebar.login": "Inicio de Sesión",
@@ -935,8 +939,6 @@
"analytics.system.activeUsers": "Usuarios Activos con Mensajes",
"analytics.system.channelTypes": "Tipos de Canales",
"analytics.system.dailyActiveUsers": "Usuarios Activos Diarios",
- "analytics.system.expiredBanner": "La licencia Empresarial vence el {date}. Tienes 15 días desde esta notificación para renovar la licencia, por favor contacta a <a href='mailto:commercial@mattermost.com'>commercial@mattermost.com</a>.",
- "analytics.system.expiringBanner": "La licencia Empresarial vence el {date}. Para renovar tu licencia, por favor contacta a <a href='mailto:commercial@mattermost.com'>commercial@mattermost.com</a>.",
"analytics.system.monthlyActiveUsers": "Usuarios Activos Mensuales",
"analytics.system.postTypes": "Mesajes, Archivos y Hashtags",
"analytics.system.privateGroups": "Grupos Privados",
@@ -1287,9 +1289,9 @@
"error.not_found.title": "Página no encontrada",
"error.not_supported.message": "La navegación privada no es compatible",
"error.not_supported.title": "Navegador no compatible",
- "error_bar.expired": "La licencia Empresarial se venció; tienes 15 días desde la fecha de vencimiento para renovar la licencia, por favor contacta a commercial@mattermost.com para más detalles",
- "error_bar.expiring": "La licencia Empresarial vence el {date}. Para renovar tu licencia, por favor contacta a commercial@mattermost.com",
- "error_bar.past_grace": "La licencia Empresarial se venció, por favor contacta a un Administrador del Sistema para más detalles",
+ "error_bar.expired": "La licencia para Empresas está vencida y algunas características pueden ser deshabilitadas. <a href='{link}' target='_blank'>Favor renovar.</a>",
+ "error_bar.expiring": "La licencia para Empresas expira el {date}. <a href='{link}' target='_blank'>Favor renovar.</a>",
+ "error_bar.past_grace": "La licencia para Empresas está vencida y algunas características pueden ser desbahilitadas. Por favor contacta a tu Adminstrador de Sistema para más detalles.",
"error_bar.preview_mode": "Modo de prueba: Las notificaciones por correo electrónico no han sido configuradas",
"file_attachment.download": "Descargar",
"file_info_preview.size": "Tamaño ",
diff --git a/webapp/i18n/fr.json b/webapp/i18n/fr.json
index a2a5bf4e7..acbf28516 100644
--- a/webapp/i18n/fr.json
+++ b/webapp/i18n/fr.json
@@ -28,7 +28,7 @@
"activity_log.sessionsDescription": "Les sessions sont créées lorsque vous vous connectez depuis un nouveau navigateur. Les sessions vous permettent d'utiliser Mattermost sans devoir vous connecter à nouveau durant un temps défini par l'administrateur système. Si vous souhaitez vous déconnecter plus tôt, utilisez le bouton \"Se déconnecter\" ci-dessous pour mettre fin à votre session.",
"activity_log_modal.android": "Android",
"activity_log_modal.androidNativeApp": "Application Android",
- "activity_log_modal.desktop": "Native Desktop App",
+ "activity_log_modal.desktop": "Application de bureau native",
"activity_log_modal.iphoneNativeApp": "Application pour iPhone",
"add_command.autocomplete": "Auto-complétion",
"add_command.autocomplete.help": "(Facultatif) Afficher les commandes slash dans la liste d'auto-complétion.",
@@ -138,7 +138,7 @@
"add_outgoing_webhook.triggerWordsTriggerWhenFullWord": "Premier mot correspond exactement à un mot déclencheur",
"add_outgoing_webhook.triggerWordsTriggerWhenStartsWith": "Le premier mot commence avec un mot déclencheur",
"admin.advance.cluster": "Haute disponibilité (Bêta)",
- "admin.advance.metrics": "Suivi des performances (Beta)",
+ "admin.advance.metrics": "Suivi des performances",
"admin.audits.reload": "Recharger les logs de l'activité utilisateur",
"admin.audits.title": "Activité de l'utilisateur",
"admin.authentication.email": "Authentification email",
@@ -217,8 +217,11 @@
"admin.customization.customEmoji": "Emoji personnalisés",
"admin.customization.enableCustomEmojiDesc": "Permet aux utilisateurs de créer leurs propres emoji. Si activé, \"Emoji Personnalisés\" est accessible en sélectionnant une équipe, en cliquant sur les trois points en haut de la barre latérale et en choisissant l'option du menu.",
"admin.customization.enableCustomEmojiTitle": "Activer les Emoji personnalisés :",
+ "admin.customization.enableLinkPreviewsDesc": "Permet aux utilisateurs d'afficher un aperçu du contenu du site web en-dessous du message, si disponible. Lorsqu'activé, les aperçus de sites web peut être activés à partir de Paramètres du compte > Options avancées > Activer les fonctionnalités expérimentales.",
+ "admin.customization.enableLinkPreviewsTitle": "Activer l'aperçu des liens:",
"admin.customization.iosAppDownloadLinkDesc": "Ajouter un lien pour télécharger l'application iOS. Les utilisateurs qui visitent le site avec un navigateur web mobile seront accueils avec une page leur permettant de télécharger l'application. Laissez ce champ vide pour ne pas afficher cette page.",
"admin.customization.iosAppDownloadLinkTitle": "Lien de téléchargement de l'app iOS :",
+ "admin.customization.linkPreviews": "Aperçu des liens",
"admin.customization.nativeAppLinks": "Liens des applications Mattermost",
"admin.customization.restrictCustomEmojiCreationAdmin": "Permet aux administrateurs système et d'équipe de créer des emoji personnalisés",
"admin.customization.restrictCustomEmojiCreationAll": "Permettre à tout le monde de créer des Emoji personnalisés",
@@ -252,16 +255,16 @@
"admin.email.mhpnsHelp": "Téléchargez l'<a href=\"https://itunes.apple.com/us/app/mattermost/id984966508?mt=8\" target=\"_blank\">application iOS Mattermost</a> depuis iTunes. Téléchargez l'<a href=\"https://play.google.com/store/apps/details?id=com.mattermost.mattermost&hl=en\" target=\"_blank\">application Android Mattermost</a> depuis le Google Play. Apprenez-en plus sur <a href=\"http://docs.mattermost.com/deployment/push.html#hosted-push-notifications-service-hpns\" target=\"_blank\">HPNS</a>.",
"admin.email.mtpns": "Utilisez iOS et Android sur iTunes et Google Play avec TPNS",
"admin.email.mtpnsHelp": "Téléchargez l'<a href=\"https://itunes.apple.com/us/app/mattermost/id984966508?mt=8\" target=\"_blank\">application iOS Mattermost</a> depuis iTunes. Téléchargez l'<a href=\"https://play.google.com/store/apps/details?id=com.mattermost.mattermost&hl=en\" target=\"_blank\">application Android Mattermost</a> depuis le Google Play. Apprenez-en plus sur <a href=\"http://docs.mattermost.com/deployment/push.html#test-push-notifications-service-tpns\" target='_blank'>TPNS</a>.",
- "admin.email.nofificationOrganizationExample": "Exemple : \"(c)MonEntreprise, 12 avenue Niel, 75017 Paris, France\"",
+ "admin.email.nofificationOrganizationExample": "Ex.: \"© MonEntreprise, 12 avenue Niel, 75017 Paris, France\"",
"admin.email.notificationDisplayDescription": "Afficher le nom du compte de messagerie utilisé lors de l'envoi de notifications par Mattermost.",
"admin.email.notificationDisplayExample": "Ex. : \"Notification Mattermost\", \"Système\", \"No-reply\"",
"admin.email.notificationDisplayTitle": "Nom affiché dans les notifications :",
"admin.email.notificationEmailDescription": "L'adresse e-mail affichée sur le compte utilisé lors de l'envoi de notifications e-mails de Mattermost.",
- "admin.email.notificationEmailExample": "Ex. : \"mattermost@yourcompany.com\", \"admin@yourcompany.com\"",
+ "admin.email.notificationEmailExample": "Ex. : \"mattermost@votreentreprise.com\", \"admin@votreentreprise.com\"",
"admin.email.notificationEmailTitle": "Notification depuis l'adresse :",
"admin.email.notificationOrganization": "Adresse e-mail du pied de page pour les notifications e-mail :",
"admin.email.notificationOrganizationDescription": "Nom de société et adresse affichés sur les notifications envoyées par e-mail, comme \"© MonEntreprise, 55 Rue du Faubourg Saint-Honoré, 75008 Paris, France\". Si ce champ est vide, il ne sera pas inclus dans les e-mails.",
- "admin.email.notificationOrganizationExample": "Exemple : \"(c)MonEntreprise, 12 avenue Niel, 75017 Paris, France\"",
+ "admin.email.notificationOrganizationExample": "Ex. : \"© MonEntreprise, 12 avenue Niel, 75017 Paris, France\"",
"admin.email.notificationsDescription": "En général, activé en production. Si activé, Mattermost essaye d'envoyer des notifications par courrier électronique. Les développeurs peuvent en revanche désactiver cette option pour gagner du temps.<br />Activer cette option retire la bannière \"Mode découverte\" (cela nécessite de se déconnecter puis se re-connecter après avoir activé l'option).",
"admin.email.notificationsTitle": "Activer les notifications par e-mail :",
"admin.email.passwordSaltDescription": "Clé de salage de 32 caractères utilisé pour générer la clé de réinitialisation du mot de passe. Générée aléatoirement à l'installation. Veuillez cliquer sur \"regénérer\" pour créer une nouvelle clé de salage.",
@@ -276,20 +279,20 @@
"admin.email.pushServerEx": "Exemple : \"http://push-test.mattermost.com\"",
"admin.email.pushServerTitle": "Serveur de notifications push :",
"admin.email.pushTitle": "Envoyer des notifications push : ",
- "admin.email.requireVerificationDescription": "En général activé en production. Si activé, Mattermost impose une vérification de l'adresse e-mail avant d'autoriser la connexion. Vous pouvez désactiver cette option en développement.",
+ "admin.email.requireVerificationDescription": "En général, activé en production. Si activé, Mattermost impose une vérification de l'adresse e-mail avant d'autoriser la connexion. Vous pouvez désactiver cette option en développement.",
"admin.email.requireVerificationTitle": "Imposer la vérification de l'adresse e-mail : ",
"admin.email.selfPush": "Spécifiez manuellement la configuration du service de notifications Push",
"admin.email.smtpPasswordDescription": " Récupérez ces informations de la part de l'administrateur de votre serveur de mails.",
- "admin.email.smtpPasswordExample": "Ex. : \"yourpassword\", \"jcuS8PuvcpGhpgHhlcpT1Mx42pnqMxQY\"",
+ "admin.email.smtpPasswordExample": "Ex. : \"votremotdepasse\", \"jcuS8PuvcpGhpgHhlcpT1Mx42pnqMxQY\"",
"admin.email.smtpPasswordTitle": "Mot de passe du serveur SMTP :",
"admin.email.smtpPortDescription": "Port du serveur SMTP.",
"admin.email.smtpPortExample": "Ex. : \"25\", \"465\", \"587\"",
"admin.email.smtpPortTitle": "Port SMTP :",
"admin.email.smtpServerDescription": "Adresse de votre serveur SMTP.",
- "admin.email.smtpServerExample": "Ex. : \"smtp. yourcompany.com\", \"email-smtp.us-east-1.amazonaws.com\"",
+ "admin.email.smtpServerExample": "Ex. : \"smtp.votreentreprise.com\", \"email-smtp.us-east-1.amazonaws.com\"",
"admin.email.smtpServerTitle": "Serveur SMTP :",
"admin.email.smtpUsernameDescription": " Récupérez ces informations de la part de l'administrateur de votre serveur de mails.",
- "admin.email.smtpUsernameExample": "Ex. : \"admin@yourcompany.com\", \"AKIADTOVBGERKLCBV\"",
+ "admin.email.smtpUsernameExample": "Ex. : \"admin@votreentreprise.com\", \"AKIADTOVBGERKLCBV\"",
"admin.email.smtpUsernameTitle": "Nom d'utilisateur SMTP :",
"admin.email.testing": "Essai en cours...",
"admin.false": "non",
@@ -310,34 +313,34 @@
"admin.general.localization.serverLocaleTitle": "Langue par défaut du serveur :",
"admin.general.log": "Journalisation",
"admin.general.policy": "Règles",
- "admin.general.policy.allowEditPostAlways": "Any time",
- "admin.general.policy.allowEditPostDescription": "Set policy on the length of time authors have to edit their messages after posting.",
+ "admin.general.policy.allowEditPostAlways": "N'importe quand",
+ "admin.general.policy.allowEditPostDescription": "Définit la durée durant laquelle l'auteur d'un message pourra modifier son message après l'avoir publié.",
"admin.general.policy.allowEditPostNever": "Jamais",
- "admin.general.policy.allowEditPostTimeLimit": "seconds after posting",
- "admin.general.policy.allowEditPostTitle": "Allow users to edit their messages:",
+ "admin.general.policy.allowEditPostTimeLimit": "secondes après publication",
+ "admin.general.policy.allowEditPostTitle": "Autoriser des utilisateurs à éditer leurs messages :",
"admin.general.policy.permissionsAdmin": "Administrateurs d'équipe et administrateurs système",
"admin.general.policy.permissionsAll": "Tous les membres de l'équipe",
"admin.general.policy.permissionsAllChannel": "Tous les membres du canal",
- "admin.general.policy.permissionsChannelAdmin": "Channel, Team and System Admins",
+ "admin.general.policy.permissionsChannelAdmin": "Canal, équipe et administrateurs système",
"admin.general.policy.permissionsDeletePostAdmin": "Administrateurs d'équipe et administrateurs système",
- "admin.general.policy.permissionsDeletePostAll": "Message authors can delete their own messages, and Administrators can delete any message",
+ "admin.general.policy.permissionsDeletePostAll": "Les auteurs peuvent supprimer leurs propres messages. Les administrateurs peuvent supprimer n'importe quel message.",
"admin.general.policy.permissionsDeletePostSystemAdmin": "Administrateurs système",
"admin.general.policy.permissionsSystemAdmin": "Administrateurs système",
- "admin.general.policy.restrictPostDeleteDescription": "Set policy on who has permission to delete messages.",
- "admin.general.policy.restrictPostDeleteTitle": "Allow which users to delete messages:",
+ "admin.general.policy.restrictPostDeleteDescription": "Définit quels sont les utilisateurs autorisés à supprimer des messages.",
+ "admin.general.policy.restrictPostDeleteTitle": "Autorise quels utilisateurs peuvent supprimer des messages :",
"admin.general.policy.restrictPrivateChannelCreationDescription": "Choisit qui peut créer des groupes privés.",
"admin.general.policy.restrictPrivateChannelCreationTitle": "Activer la création de groupes privés pour :",
"admin.general.policy.restrictPrivateChannelDeletionCommandLineToolLink": "outil en ligne de commande",
"admin.general.policy.restrictPrivateChannelDeletionDescription": "Choisit qui peut supprimer des groupes privés. Les canaux supprimés peuvent être récupérés de la base de données en utilisant {commandLineToolLink}.",
"admin.general.policy.restrictPrivateChannelDeletionTitle": "Activer la suppression de groupes privés pour :",
- "admin.general.policy.restrictPrivateChannelManagementDescription": "Choisit qui peut renommer et définir l'en-tête ou la description des groupes privés.",
+ "admin.general.policy.restrictPrivateChannelManagementDescription": "Choisit qui peut renommer et définir l'entête ou la description des groupes privés.",
"admin.general.policy.restrictPrivateChannelManagementTitle": "Activer le renommage de groupes privés pour :",
"admin.general.policy.restrictPublicChannelCreationDescription": "Choisit qui peut créer des canaux publics.",
"admin.general.policy.restrictPublicChannelCreationTitle": "Activer la création de canaux publics pour :",
"admin.general.policy.restrictPublicChannelDeletionCommandLineToolLink": "outil en ligne de commande",
"admin.general.policy.restrictPublicChannelDeletionDescription": "Choisit qui peut supprimer des canaux publics. Les canaux supprimés peuvent être récupérés de la base de données en utilisant {commandLineToolLink}.",
"admin.general.policy.restrictPublicChannelDeletionTitle": "Activer la suppression de canaux publics pour :",
- "admin.general.policy.restrictPublicChannelManagementDescription": "Choisit qui peut renommer et définir l'en-tête ou la description des canaux publics.",
+ "admin.general.policy.restrictPublicChannelManagementDescription": "Choisit qui peut renommer et définir l'entête ou la description des canaux publics.",
"admin.general.policy.restrictPublicChannelManagementTitle": "Activer le renommage de canaux publics pour :",
"admin.general.policy.teamInviteDescription": "Choisir qui peut inviter d'autres personnes à une équipe en utilisant <b>Inviter un nouveau membre</b> pour inviter des nouveaux utilisateurs par e-mail, ou l'option <b>Obtenir un lien d'invitation d'équipe</b> du menu principal. Si l'option <b>Obtenir un lien d'invitation d'équipe</b> est utilisée pour partager un lien, vous pouvez faire expirer le code d'invitation depuis <b>Configuration de l'équipe</b> > <b>Code d'invitation</b> une fois que les utilisateurs désirés ont rejoint l'équipe.",
"admin.general.policy.teamInviteTitle": "Autoriser l'envoi d'invitation depuis :",
@@ -376,7 +379,7 @@
"admin.image.amazonS3BucketExample": "Ex. : \"mattermost-media\"",
"admin.image.amazonS3BucketTitle": "Bucket S3 Amazon :",
"admin.image.amazonS3EndpointDescription": "Nom d'hôte de votre fournisseur de stockage compatible S3. Par défaut : 's3.amazonaws.com'.",
- "admin.image.amazonS3EndpointExample": "E.g.: \"s3.amazonaws.com\"",
+ "admin.image.amazonS3EndpointExample": "Ex. : \"s3.amazonaws.com\"",
"admin.image.amazonS3EndpointTitle": "Endpoint Amazon S3 :",
"admin.image.amazonS3IdDescription": "Demandez cette information à votre administrateur AWS.",
"admin.image.amazonS3IdExample": "Ex. : \"AKIADTOVBGERKLCBV\"",
@@ -460,7 +463,7 @@
"admin.ldap.portDesc": "Le port utilisé par Mattermost pour vous connecter au serveur LDAP. Par défaut : 389.",
"admin.ldap.portEx": "Ex. : \"389\"",
"admin.ldap.portTitle": "Port du serveur LDAP :",
- "admin.ldap.positionAttrDesc": "(Optionnel) L'attribut du serveur AD/LDAP qui sera utilisé pour le champ \"poste\" dans Mattermost.",
+ "admin.ldap.positionAttrDesc": "(Optionnel) L'attribut du serveur AD/LDAP qui sera utilisé pour le champ \"rôle\" de Mattermost.",
"admin.ldap.positionAttrEx": "Ex. : \"titre\"",
"admin.ldap.positionAttrTitle": "Attribut de rôle :",
"admin.ldap.queryDesc": "Valeur du délai d'attente pour les requêtes au serveur AD/LDAP. Augmentez cette valeur si vous rencontrez des erreurs liées à un serveur AD/LDAP trop lent.",
@@ -481,7 +484,7 @@
"admin.ldap.testSuccess": "Test d'AD/LDAP réussi avec succès",
"admin.ldap.uernameAttrDesc": "Attribut du serveur LDAP utilisé pour le champ \"nom d'utilisateur\" dans Mattermost. Utilisez de préférence le même champ que l'attribut \"identifiant d'utilisateur\".",
"admin.ldap.userFilterDisc": "Entrez éventuellement un filtre LDAP à utiliser lors de la recherche d'objets utilisateur. Seuls les utilisateurs sélectionnés par la requête seront en mesure d'accéder à Mattermost . Pour Active Directory, la requête pour filtrer les utilisateurs désactivés est (&(objectCategory=Person)(!(UserAccountControl:1.2.840.113556.1.4.803:=2))).",
- "admin.ldap.userFilterEx": "Ex. : \"(objectClass=utilisateur)\"",
+ "admin.ldap.userFilterEx": "Ex. : \"(objectClass=user)\"",
"admin.ldap.userFilterTitle": "Filtre utilisateur :",
"admin.ldap.usernameAttrEx": "Ex. : \"sAMAccountName\"",
"admin.ldap.usernameAttrTitle": "Attribut \"nom d'utilisateur\" :",
@@ -527,9 +530,9 @@
"admin.metrics.enableDescription": "Lorsqu'activé, Mattermost activera la collecte des rapports de performance et de profilage. Veuillez vous référer à la <a href=\"http://docs.mattermost.com/deployment/metrics.html\" target='_blank'>documentation</a> pour en savoir plus sur la configuration du suivi des performances de Mattermost.",
"admin.metrics.enableTitle": "Activer le suivi des performances :",
"admin.metrics.listenAddressDesc": "L'adresse d'écoute du serveur pour publier les mesures de performances.",
- "admin.metrics.listenAddressEx": "Ex. : \":8065\"",
+ "admin.metrics.listenAddressEx": "Ex. : \":8067\"",
"admin.metrics.listenAddressTitle": "Adresse IP du serveur :",
- "admin.mfa.bannerDesc": "<a href='https://docs.mattermost.com/deployment/auth.html' target='_blank'>Multi-factor authentication</a> is available for accounts with AD/LDAP or email login. If other login methods are used, MFA should be configured with the authentication provider.",
+ "admin.mfa.bannerDesc": "L'<a href='https://docs.mattermost.com/deployment/auth.html' target='_blank'>authentification multi-facteurs (MFA)</a> est disponible pour les comptes se connectant à l'aide de AD/LDAP ou d'une adresse e-mail. Si d'autres méthodes d'authentification sont utilisées, MFA doit être configuré avec le fournisseur d'authentification.",
"admin.mfa.cluster": "Haute",
"admin.mfa.title": "Authentification multi-facteurs",
"admin.nav.help": "Aide",
@@ -566,9 +569,9 @@
"admin.password.requirementsDescription": "Lettres obligatoires pour un mot de passe valide.",
"admin.password.symbol": "Au moins un symbole (ex : \"~!@#$%^&*()\")",
"admin.password.uppercase": "Au moins une majuscule",
- "admin.privacy.showEmailDescription": "When false, hides the email address of members from everyone except System Administrators.",
+ "admin.privacy.showEmailDescription": "Si désactivé, cache l'adresse e-mail des membres de tout le monde sauf des administrateurs système.",
"admin.privacy.showEmailTitle": "Afficher l'adresse e-mail : ",
- "admin.privacy.showFullNameDescription": "When false, hides the full name of members from everyone except System Administrators. Username is shown in place of full name.",
+ "admin.privacy.showFullNameDescription": "Si désactivé, cache le nom complet des membres de tout le monde sauf des administrateurs système. Le nom d'utilisateur s'affiche alors à la place du nom complet.",
"admin.privacy.showFullNameTitle": "Afficher le nom complet : ",
"admin.purge.button": "Purger tous les caches",
"admin.purge.loading": " Chargement…",
@@ -576,13 +579,13 @@
"admin.purge.purgeFail": "Impossible de purger : {error}",
"admin.rate.enableLimiterDescription": "Si activé, les APIs sont limitées comme spécifié ci-dessous.",
"admin.rate.enableLimiterTitle": "Limiter l'accès aux API : ",
- "admin.rate.httpHeaderDescription": "Quand ce champ est rempli, les flux des requêtes sont limités par l'en-tête HTTP spécifié (par exemple \"X-Real-IP\" avec Nginx, \"X-Forwarded-For\" pour AmazonELB)",
+ "admin.rate.httpHeaderDescription": "Lorsque rempli, fait varier les limites de fréquence par l'entête HTTP spécifié (par exemple lorsque NGINX est configuré avec \"X-Real-IP\", lorsque AmazonELB est configuré avec \"X-Forwarded-For\")",
"admin.rate.httpHeaderExample": "Ex. : \"X-Real-IP\", \"X-Forwarded-For\"",
- "admin.rate.httpHeaderTitle": "Varier le taux limite par un en-tête HTTP",
+ "admin.rate.httpHeaderTitle": "Fait varier les limites de fréquence par l'entête HTTP:",
"admin.rate.maxBurst": "Limite maximale de dépassement :",
"admin.rate.maxBurstDescription": "Nombre maximum de requêtes autorisées à dépasser le seuil limite de requêtes par seconde.",
"admin.rate.maxBurstExample": "Ex. : \"100\"",
- "admin.rate.memoryDescription": "Nombre maximum de sessions utilisateur connectées au système, comme indiqué dans les paramètres \"Adresse distante Vary By\" et \"En-tête HTTP Vary By\" ci-dessous.",
+ "admin.rate.memoryDescription": "Nombre maximum de sessions utilisateur connectées au système, comme indiqué dans les paramètres \"Adapter la limite de fréquence en fonction de l'adresse distante\" et \"Fait varier les limites de fréquence par l'entête HTTP\" ci-dessous.",
"admin.rate.memoryExample": "Ex. : \"10000\"",
"admin.rate.memoryTitle": "Taille du stockage en mémoire :",
"admin.rate.noteDescription": "Modifier des paramètres dans cette section nécessite un redémarrage du serveur.",
@@ -591,7 +594,7 @@
"admin.rate.queriesExample": "Ex. : \"10\"",
"admin.rate.queriesTitle": "Nombre maximum de requêtes par seconde :",
"admin.rate.remoteDescription": "Si activé, l'API est limitée au moyen de l'adresse IP du client.",
- "admin.rate.remoteTitle": "Adapter la limite en fonction de l'adresse distante : ",
+ "admin.rate.remoteTitle": "Adapter la limite de fréquence en fonction de l'adresse distante : ",
"admin.rate.title": "Configuration des limites de débit",
"admin.recycle.button": "Recycler les connexions à la base de données",
"admin.recycle.loading": " Recyclage...",
@@ -689,7 +692,7 @@
"admin.service.developerDesc": "Si activé, les erreurs Javascript sont affichées dans une barre rouge en haut de l'interface utilisateur. Ceci n'est pas recommandé sur un serveur de production. ",
"admin.service.developerTitle": "Activer le mode développeur : ",
"admin.service.enforcMfaTitle": "Imposer l'authentification multi-facteurs :",
- "admin.service.enforceMfaDesc": "When true, <a href='https://docs.mattermost.com/deployment/auth.html' target='_blank'>multi-factor authentication</a> is required for login. New users will be required to configure MFA on signup. Logged in users without MFA configured are redirected to the MFA setup page until configuration is complete.<br/><br/>If your system has users with login methods other than AD/LDAP and email, MFA must be enforced with the authentication provider outside of Mattermost.",
+ "admin.service.enforceMfaDesc": "Lorsqu'activé, l'<a href='https://docs.mattermost.com/deployment/auth.html' target='_blank'>authentification multi-facteurs (MFA)</a> est requise pour la connexion. Les nouveaux utilisateurs devront configurer MFA lors de leur inscription. Les utilisateurs connectés sans MFA configuré seront redirigés vers la page de configuration MFA jusqu'à ce que la configuration soit terminée.<br/><br/>Si votre système dispose d'utilisateurs se connectant autrement que par AD/LDAP ou une adresse e-mail, MFA devra être appliqué avec un fournisseur d'authentification extérieur à Mattermost.",
"admin.service.forward80To443": "Transférer le port 80 vers le port 443 :",
"admin.service.forward80To443Description": "Faire suivre le trafic non chiffré du port 80 vers le port sécurisé 443",
"admin.service.googleDescription": "Définissez cette clé pour activer l'affichage des titres pour les aperçus de vidéos YouTube. Sans la clé, les aperçus YouTube seront créés à partir des liens apparaissant des messages ou commentaires mais ils ne montreront pas le titre de la vidéo. Regardez un <a href=\"https://www.youtube.com/watch?v=Im69kzhpR3I\" target=\"_blank\">tutoriel Google Developers</a> pour des instructions sur comment obtenir une clé.",
@@ -706,7 +709,7 @@
"admin.service.listenAddress": "Adresse IP du serveur :",
"admin.service.listenDescription": "L'adresse et le port sur laquelle se lier et écouter. Spécifier \":8065\" se liera sur toutes les interfaces réseau. Spécifier \"127.0.0.1:8065\" se liera uniquement sur l'interface réseau disposant de cette adresse IP. Si vous choisissez un port de bas niveau (également appelés \"ports systèmes\" ou \"ports bien connus\", dans l'intervalle 0-1023), vous devez disposer des permissions pour vous lier sur ces ports. Sous Linux, vous pouvez utiliser : \"sudo setcap cap_net_bind_service=+ep ./bin/platform\" pour autoriser Mattermost à se lier sur ces ports bien connus.",
"admin.service.listenExample": "Ex. : \":8065\"",
- "admin.service.mfaDesc": "When true, users with AD/LDAP or email login can add multi-factor authentication to their account using Google Authenticator.",
+ "admin.service.mfaDesc": "Si activé, les utilisateurs se connectant à l'aide de AD/LDAP ou d'une adresse e-mail peuvent ajouter l'authentification multi-facteurs (MFA) à leur compte en utilisant Google Authenticator.",
"admin.service.mfaTitle": "Activité l’authentification multi-facteurs:",
"admin.service.mobileSessionDays": "Durée de la session sur les applis mobiles (en jours) :",
"admin.service.mobileSessionDaysDesc": "Le nombre de jours entre la dernière fois qu'un utilisateur a spécifié ses identifiants et l'expiration de la session de l'utilisateur. Après le changement de ce paramètre, la nouvelle durée de session prendra effet la prochaine fois que les utilisateurs saisiront leurs identifiants.",
@@ -722,7 +725,7 @@
"admin.service.sessionCacheDesc": "Durée pendant laquelle une session est gardée en mémoire.",
"admin.service.sessionDaysEx": "Ex. : \"30\"",
"admin.service.siteURL": "URL du site :",
- "admin.service.siteURLDescription": "L'URL, incluant le numéro de port et le protocol, que les utilisateurs utilisent pour accéder à Mattermost. Ce champ peut être laissé vide à moins que vous ne configuriez l'envoi d'email par lots dans <b>Notifications > Email</b>. Lorsque le champ est vide, l'URL est configurée automatiquement sur base du trafic entrant.",
+ "admin.service.siteURLDescription": "L'URL, incluant le numéro de port et le protocol, que les utilisateurs utilisent pour accéder à Mattermost. Ce champ peut être laissé vide à moins que vous ne configuriez l'envoi d'email par lot dans <b>Notifications > Email</b>. Lorsque le champ est vide, l'URL est configurée automatiquement sur base du trafic entrant.",
"admin.service.siteURLExample": "Ex. : \"https://mattermost.example.com:1234\"",
"admin.service.ssoSessionDays": "Durée de la session SSO (en jours) :",
"admin.service.ssoSessionDaysDesc": "Le nombre de jours entre la dernière fois qu'un utilisateur a spécifié ses identifiants et l'expiration de la session de l'utilisateur. Si la méthode d'authentification est SAML ou GitLab, l'utilisateur pourra être automatiquement connecté à nouveau dans Mattermost s'ils sont déjà connectés dans SAML ou GitLab. Après le changement de ce paramètre, il prendra effet la prochaine fois que les utilisateurs saisiront leurs identifiants.",
@@ -739,7 +742,7 @@
"admin.service.webhooksDescription": "Si activé, les webhooks entrants seront autorisés. Pour aider à combattre les attaques d'hameçonnage, tous les messages de webhooks seront étiquetés par un label BOT. Consultez la <a href='http://docs.mattermost.com/developer/webhooks-incoming.html' target='_blank'>documentation</a> pour en apprendre davantage.",
"admin.service.webhooksTitle": "Activer les webhooks entrants : ",
"admin.service.writeTimeout": "Délai d'attente d'écriture :",
- "admin.service.writeTimeoutDescription": "Si vous utilisez HTTP (non sécurisé), il s'agit du temps maximum autorisé à partir du moment auquel les en-têtes sont lus jusqu'au moment auquel la réponse est écrite. Si vous utilisez le protocole HTTPS, c'est le temps total à partir du moment où la connexion est acceptée jusqu'au moment où la réponse est écrite.",
+ "admin.service.writeTimeoutDescription": "Si vous utilisez HTTP (non sécurisé), il s'agit du temps maximum autorisé à partir du moment auquel les entêtes sont lus jusqu'au moment auquel la réponse est écrite. Si vous utilisez le protocole HTTPS, c'est le temps total à partir du moment où la connexion est acceptée jusqu'au moment où la réponse est écrite.",
"admin.sidebar.addTeamSidebar": "Afficher l'équipe dans le menu",
"admin.sidebar.advanced": "Options avancées",
"admin.sidebar.audits": "Conformité et vérification",
@@ -764,11 +767,12 @@
"admin.sidebar.ldap": "AD/LDAP",
"admin.sidebar.legalAndSupport": "Mentions légales",
"admin.sidebar.license": "Édition et licence",
+ "admin.sidebar.linkPreviews": "Aperçu des liens",
"admin.sidebar.localization": "Localisation",
"admin.sidebar.logging": "Enregistrement",
"admin.sidebar.login": "S’identifier",
"admin.sidebar.logs": "Journaux",
- "admin.sidebar.metrics": "Suivi des performances (Beta)",
+ "admin.sidebar.metrics": "Suivi des performances",
"admin.sidebar.nativeAppLinks": "Liens des applications Mattermost",
"admin.sidebar.notifications": "Notifications",
"admin.sidebar.oauth": "OAuth 2.0",
@@ -845,7 +849,7 @@
"admin.team.maxChannelsExample": "Ex. : \"100\"",
"admin.team.maxChannelsTitle": "Nombre maximum de canaux par équipe :",
"admin.team.maxNotificationsPerChannelDescription": "Nombre utilisateurs maximum au delà duquel les messages comprenant des mentions @all, @here, et @channel n'engendreront plus l'envoi de notifications à cause des performances.",
- "admin.team.maxNotificationsPerChannelExample": "Ex. : \"10000\"",
+ "admin.team.maxNotificationsPerChannelExample": "Ex. : \"1000\"",
"admin.team.maxNotificationsPerChannelTitle": "Nombre maximum de notifications par canal :",
"admin.team.maxUsersDescription": "Nombre maximum d'utilisateurs par équipe, actifs et inactifs.",
"admin.team.maxUsersExample": "Ex. : \"25\"",
@@ -865,13 +869,13 @@
"admin.team.siteNameDescription": "Nom du service affiché dans les écrans de connexion et l'interface.",
"admin.team.siteNameExample": "Ex. : \"Mattermost\"",
"admin.team.siteNameTitle": "Nom du site :",
- "admin.team.teamCreationDescription": "Si faux, seuls les administrateurs système peuvent créer des équipes.",
+ "admin.team.teamCreationDescription": "Si désactivé, seuls les administrateurs système peuvent créer des équipes.",
"admin.team.teamCreationTitle": "Autoriser la création d'équipes : ",
"admin.team.upload": "Télécharger",
"admin.team.uploadDesc": "Personnalisez votre expérience utilisateur en ajoutant une image personnalisée sur votre écran de connexion. Taille d'image recommandée inférieure à 2Mio.",
"admin.team.uploaded": "téléchargement terminé!",
"admin.team.uploading": "téléchargement..",
- "admin.team.userCreationDescription": "Si désactivé, la possibilité de créer des comptes est désactivée.",
+ "admin.team.userCreationDescription": "Si désactivé, la possibilité de créer des comptes est désactivée. Appuyer sur le bouton de création de compte affichera une erreur lorsqu'il sera utilisé.",
"admin.team.userCreationTitle": "Autoriser la création de comptes : ",
"admin.team_analytics.activeUsers": "Utilisateurs actifs avec messages",
"admin.team_analytics.totalPosts": "Nombre total de messages",
@@ -912,13 +916,13 @@
"admin.webrtc.gatewayWebsocketUrlTitle": "URL de la passerelle WebSocket :",
"admin.webrtc.stunUriDescription": "Spécifiez votre URI STUN sous la forme stun:<your-stun-url>:<port>. STUN est un protocole réseau standardisé permettant aux clients finaux de déterminer leur adresse IP publique lorsqu'ils sont situés derrière un NAT.",
"admin.webrtc.stunUriExample": "Ex. : \"stun:webrtc.mattermost.com:5349\"",
- "admin.webrtc.stunUriTitle": "STUN URI",
+ "admin.webrtc.stunUriTitle": "URI STUN:",
"admin.webrtc.turnSharedKeyDescription": "Spécifiez votre clé partagée pour le serveur TURN. Elle est utilisée pour créer des mots de passe dynamiques pour établir la connexion. Chaque mot de passe est valide pendant une période de temps assez courte.",
"admin.webrtc.turnSharedKeyExample": "Ex. : \"bXdkOWQxc3d0Ynk3emY5ZmsxZ3NtazRjaWg=\"",
"admin.webrtc.turnSharedKeyTitle": "Clé partagée TURN :",
"admin.webrtc.turnUriDescription": "Spécifiez votre URI TURN sous la forme turn:<your-turn-url>:<port>. TURN est un protocole réseau standardisé permettant aux clients finaux d'établir une connexion en utilisant une adresse IP publique comme relai lorsque ces clients sont situés derrière un NAT symétrique.",
"admin.webrtc.turnUriExample": "Ex. : \"turn:webrtc.mattermost.com:5349\"",
- "admin.webrtc.turnUriTitle": "URI TURN",
+ "admin.webrtc.turnUriTitle": "URI TURN:",
"admin.webrtc.turnUsernameDescription": "Spécifiez votre nom d'utilisateur pour le serveur TURN.",
"admin.webrtc.turnUsernameExample": "Ex. : \"monnomdutilisateur\"",
"admin.webrtc.turnUsernameTitle": "Nom d'utilisateur TURN :",
@@ -934,10 +938,8 @@
"analytics.chart.meaningful": "Pas assez de données pour afficher quelque chose de pertinent.",
"analytics.system.activeUsers": "Utilisateurs actifs avec messages",
"analytics.system.channelTypes": "Types de canaux",
- "analytics.system.dailyActiveUsers": "Daily Active Users",
- "analytics.system.expiredBanner": "La licence Entreprise a expiré le {date}. Vous avez 15 jours à compter de cette date pour renouveler la licence, veuillez contacter <a href='mailto:commercial@mattermost.com'>commercial@mattermost.com</a>.",
- "analytics.system.expiringBanner": "La licence Entreprise expire le {date}. Pour renouveler votre licence, veuillez contacter<a href='mailto:commercial@mattermost.com'>commercial@mattermost.com</a>.",
- "analytics.system.monthlyActiveUsers": "Monthly Active Users",
+ "analytics.system.dailyActiveUsers": "Utilisateurs actifs quotidien",
+ "analytics.system.monthlyActiveUsers": "Utilisateurs actifs mensuel",
"analytics.system.postTypes": "Messages, fichiers et hashtags",
"analytics.system.privateGroups": "Groupes privés",
"analytics.system.publicChannels": "Canaux publics",
@@ -966,18 +968,18 @@
"analytics.team.title": "Statistiques d'équipe pour {team}",
"analytics.team.totalPosts": "Nombre de messages",
"analytics.team.totalUsers": "Nombre d'utilisateurs",
- "api.channel.add_member.added": "{addedUsername} added to the channel by {username}",
- "api.channel.delete_channel.archived": "{username} has archived the channel.",
- "api.channel.join_channel.post_and_forget": "{username} has joined the channel.",
- "api.channel.leave.left": "{username} has left the channel.",
- "api.channel.post_update_channel_displayname_message_and_forget.updated_from": "{username} updated the channel display name from: {old} to: {new}",
- "api.channel.post_update_channel_header_message_and_forget.removed": "{username} removed the channel header (was: {old})",
- "api.channel.post_update_channel_header_message_and_forget.updated_from": "{username} updated the channel header from: {old} to: {new}",
- "api.channel.post_update_channel_header_message_and_forget.updated_to": "{username} updated the channel header to: {new}",
- "api.channel.remove_member.removed": "{removedUsername} was removed from the channel",
- "app.channel.post_update_channel_purpose_message.removed": "{username} removed the channel purpose (was: {old})",
- "app.channel.post_update_channel_purpose_message.updated_from": "{username} updated the channel purpose from: {old} to: {new}",
- "app.channel.post_update_channel_purpose_message.updated_to": "{username} updated the channel purpose to: {new}",
+ "api.channel.add_member.added": "{addedUsername} a été ajouté au canal par {username}",
+ "api.channel.delete_channel.archived": "{username} a archivé le canal.",
+ "api.channel.join_channel.post_and_forget": "{username} a rejoint le canal.",
+ "api.channel.leave.left": "{username} a quitté le canal.",
+ "api.channel.post_update_channel_displayname_message_and_forget.updated_from": "{username} a mis à jour le nom d'affichage du canal de: {old} à: {new}",
+ "api.channel.post_update_channel_header_message_and_forget.removed": "{username} a supprimé l'entête du canal (précédemment: {old})",
+ "api.channel.post_update_channel_header_message_and_forget.updated_from": "{username} a mis à jour l'entête du canal de : {old} en : {new}",
+ "api.channel.post_update_channel_header_message_and_forget.updated_to": "{username} a mis à jour l'entête du canal en : {new}",
+ "api.channel.remove_member.removed": "{removedUsername} a été retiré du canal",
+ "app.channel.post_update_channel_purpose_message.removed": "{username} a supprimé la description du canal (précédemment: {old})",
+ "app.channel.post_update_channel_purpose_message.updated_from": "{username} a mis à jour la description du canal de: {old} en: {new}",
+ "app.channel.post_update_channel_purpose_message.updated_to": "{username} a mis à jour la description du canal en: {new}",
"audit_table.accountActive": "Compte activé",
"audit_table.accountInactive": "Compte désactivé",
"audit_table.action": "Action",
@@ -1000,9 +1002,9 @@
"audit_table.failedLogin": "ÉCHEC de la connexion",
"audit_table.failedOAuthAccess": "Impossible d'autoriser un nouvel accès à un service OAuth - L'URI de redirection ne correspond pas à l'URI de callback déjà enregistrée",
"audit_table.failedPassword": "Impossible de modifier le mot de passe pour un utilisateur connecté via OAuth",
- "audit_table.failedWebhookCreate": "Impossible de créer le webhook - autorisation insuffisante pour ce canal",
+ "audit_table.failedWebhookCreate": "Impossible de créer le webhook - permissions insuffisantes pour ce canal",
"audit_table.failedWebhookDelete": "Impossible de supprimer un webhook - conditions non remplies",
- "audit_table.headerUpdated": "En-tête du canal/groupe {channelName} mis à jour",
+ "audit_table.headerUpdated": "Entête du canal/groupe {channelName} a été mis à jour",
"audit_table.ip": "Adresse IP",
"audit_table.licenseRemoved": "Licence supprimée avec succès",
"audit_table.loginAttempt": " (Tentative de connexion)",
@@ -1048,11 +1050,11 @@
"calling_screen": "Appel",
"center_panel.recent": "Veuillez cliquer ici pour voir les messages récents. ",
"change_url.close": "Fermer",
- "change_url.endWithLetter": "Doit se terminer par une lettre ou un nombre",
+ "change_url.endWithLetter": "l'URL doit se terminer par une lettre ou un nombre.",
"change_url.invalidUrl": "URL non valide",
- "change_url.longer": "URL must be two or more characters.",
- "change_url.noUnderscore": "Ne peux pas contenir deux tirets de suite.",
- "change_url.startWithLetter": "Doit commencer par une lettre ou un nombre",
+ "change_url.longer": "L'URL doit comporter 2 caractères ou plus.",
+ "change_url.noUnderscore": "L'URL ne peut pas contenir deux tirets de suite.",
+ "change_url.startWithLetter": "L'URL doit commencer par une lettre ou un nombre.",
"channelHeader.addToFavorites": "Ajouter aux favoris",
"channelHeader.removeFromFavorites": "Retirer des favoris",
"channel_flow.alreadyExist": "Il existe déjà un canal avec cette URL",
@@ -1086,7 +1088,7 @@
"channel_header.webrtc.unavailable": "Passer un nouvel appel n'est pas possible tant que l'appel en cours n'a pas été terminé",
"channel_info.about": "À propos de",
"channel_info.close": "Fermer",
- "channel_info.header": "En-tête :",
+ "channel_info.header": "Entête :",
"channel_info.id": "ID : ",
"channel_info.name": "Nom",
"channel_info.notFound": "Aucun canal",
@@ -1104,12 +1106,12 @@
"channel_loader.uploadedFile": " téléchargé un fichier",
"channel_loader.uploadedImage": " téléchargé une image",
"channel_loader.wrote": " a écrit : ",
- "channel_members_dropdown.channel_admin": "Channel Admin",
- "channel_members_dropdown.channel_member": "Membres du canal",
- "channel_members_dropdown.make_channel_admin": "Make Channel Admin",
- "channel_members_dropdown.make_channel_member": "Make Channel Member",
- "channel_members_dropdown.remove_from_channel": "Remove From Channel",
- "channel_members_dropdown.remove_member": "Remove Member",
+ "channel_members_dropdown.channel_admin": "Administrateur du canal",
+ "channel_members_dropdown.channel_member": "Membre du canal",
+ "channel_members_dropdown.make_channel_admin": "Définir comme administrateur du canal",
+ "channel_members_dropdown.make_channel_member": "Définir comme membre du canal",
+ "channel_members_dropdown.remove_from_channel": "Supprimer du canal",
+ "channel_members_dropdown.remove_member": "Supprimer un membre",
"channel_members_modal.addNew": " Ajouter des nouveaux membres",
"channel_members_modal.members": " Membres",
"channel_modal.cancel": "Annuler",
@@ -1119,9 +1121,9 @@
"channel_modal.displayNameError": "Ce champ est obligatoire",
"channel_modal.edit": "Modifier",
"channel_modal.group": "Groupe",
- "channel_modal.header": "En-tête",
- "channel_modal.headerEx": "E.g.: \"[Link Title](http://example.com)\"",
- "channel_modal.headerHelp": "Définit le texte qui apparaitra en en-tête de {term} en regard du nom du {term}. Par exemple, saisissez des liens fréquemment utilisés en tapant [Lien de titre](http://exemple.com).",
+ "channel_modal.header": "Entête",
+ "channel_modal.headerEx": "Ex. : \"[Titre du lien](http://exemple.com)\"",
+ "channel_modal.headerHelp": "Définit le texte qui apparaîtra comme entête de {term} en regard du nom du {term}. Par exemple, saisissez des liens fréquemment utilisés en tapant [Lien de titre](http://exemple.com).",
"channel_modal.modalTitle": "Nouveau ",
"channel_modal.name": "Nom",
"channel_modal.nameEx": "Exemple : \"Problèmes\", \"Marketing\", \"Éducation\"",
@@ -1131,8 +1133,8 @@
"channel_modal.publicChannel1": "Créer un canal public",
"channel_modal.publicChannel2": "Crée un canal public que tout le monde peut rejoindre. ",
"channel_modal.purpose": "Description",
- "channel_modal.purposeEx": "E.g.: \"A channel to file bugs and improvements\"",
- "channel_notification.push": "Notifications push mobile",
+ "channel_modal.purposeEx": "Ex. : \"Un canal pour rapporter des bogues ou des améliorations\"",
+ "channel_notification.push": "Envoyer des notifications push mobiles",
"channel_notifications.allActivity": "Pour toute l'activité",
"channel_notifications.allUnread": "Pour les messages non-lus",
"channel_notifications.globalDefault": "Par défaut ({notifyLevel})",
@@ -1140,13 +1142,13 @@
"channel_notifications.never": "Jamais",
"channel_notifications.onlyMentions": "Seulement pour les mentions",
"channel_notifications.override": "Choisir une autre option que \"Par défaut\" remplacera le réglage par défaut. Les notifications sur le bureau sont disponibles sur Firefox, Safari et Chrome.",
- "channel_notifications.overridePush": "Selecting an option other than \"Global default\" will override the global notification settings for mobile push notifications in account settings. Push notifications must be enabled by the System Admin.",
+ "channel_notifications.overridePush": "La sélection d'une option autre que \"par défaut\" remplacera les paramètres de notification pour les notifications push mobiles dans les paramètres du compte. Les notifications push doit être activées par l'administrateur système.",
"channel_notifications.preferences": "Préférences de notification pour ",
"channel_notifications.sendDesktop": "Envoyer des notifications sur le bureau",
"channel_notifications.unreadInfo": "Le nom du canal est en gras dans la barre latérale lorsqu'il y a des messages non-plus. Choisir \"Seulement pour les mentions\" mettra en gras le canal seulement si vous être mentionné.",
"channel_select.placeholder": "--- Sélectionnez un canal ---",
"channel_switch_modal.dm": "(Message privé)",
- "channel_switch_modal.failed_to_open": "Failed to open channel.",
+ "channel_switch_modal.failed_to_open": "Impossible d'ouvrir le canal.",
"channel_switch_modal.help": "Saisissez le nom du canal. Utilisez ↑ ↓ pour parcourir, TAB pour sélectionner, ↵ pour confirmer, ESC pour rejeter",
"channel_switch_modal.not_found": "Aucune correspondance trouvée.",
"channel_switch_modal.submit": "Basculer",
@@ -1221,7 +1223,7 @@
"create_team.team_url.required": "Ce champ est obligatoire",
"create_team.team_url.taken": "Cette URL est déjà prise ou contient un mot réservé",
"create_team.team_url.teamUrl": "URL d’équipe",
- "create_team.team_url.unavailable": "cette url est invalide. Essayer en une autre.",
+ "create_team.team_url.unavailable": "Cette URL est indisponible. Veuillez en spécifier une autre.",
"create_team.team_url.webAddress": "Choisissez l’adresse Web de votre nouvelle équipe :",
"custom_emoji.empty": "Aucun emoji personnalisé",
"custom_emoji.header": "Emoji personnalisés",
@@ -1240,11 +1242,11 @@
"delete_post.question": "Voulez-vous vraiment supprimer ce {term} ?",
"delete_post.warning": "Ce message a {count} commentaire(s).",
"edit_channel_header_modal.cancel": "Annuler",
- "edit_channel_header_modal.description": "Modifiez le texte affiché à côté du nom du canal dans l'en-tête du canal.",
- "edit_channel_header_modal.error": "L'en-tête du canal est trop long, saisissez un texte plus court",
+ "edit_channel_header_modal.description": "Modifiez le texte affiché à côté du nom du canal dans l'entête du canal.",
+ "edit_channel_header_modal.error": "L'entête du canal est trop long, saisissez un texte plus court",
"edit_channel_header_modal.save": "Enregistrer",
- "edit_channel_header_modal.title": "Modifier l'en-tête de {channel}",
- "edit_channel_header_modal.title_dm": "Modifier l'en-tête",
+ "edit_channel_header_modal.title": "Modifier l'entête de {channel}",
+ "edit_channel_header_modal.title_dm": "Modifier l'entête",
"edit_channel_purpose_modal.body": "Décrit de quelle manière ce {type} devrait être utilisé. Ce texte apparaît dans la liste des canaux dans le menu \"Suite...\" et guide les personnes pour décider si elles devraient le rejoindre ou non.",
"edit_channel_purpose_modal.cancel": "Annuler",
"edit_channel_purpose_modal.channel": "Canal",
@@ -1287,9 +1289,9 @@
"error.not_found.title": "Page non trouvée",
"error.not_supported.message": "La navigation privée n'est pas prise en charge.",
"error.not_supported.title": "Le navigateur n'est pas pris en charge",
- "error_bar.expired": "La licence Entreprise a expiré. Vous disposez de 15 jours à compter de l'expiration pour renouveler la licence, veuillez contacter commercial@mattermost.com pour plus d'informations",
- "error_bar.expiring": "La licence Entreprise expire le {date}. Pour renouveler votre licence, veuillez contacter commercial@mattermost.com",
- "error_bar.past_grace": "La licence Entreprise a expiré, veuillez contacter votre administrateur système pour plus d'informations",
+ "error_bar.expired": "La licence entreprise a expiré et certaines fonctionnalités peuvent être désactivées. <a href='{link}' target='_blank'>Veuillez renouveler</a>.",
+ "error_bar.expiring": "La licence entreprise expire le {date}. <a href='{link}' target='_blank'>Veuillez renouveler</a>.",
+ "error_bar.past_grace": "La licence entreprise a expiré et certaines fonctionnalités peuvent être désactivées. Veuillez contacter votre administrateur système pour plus d'informations.",
"error_bar.preview_mode": "Mode découverte : Les notifications par e-mail ne sont pas configurées",
"file_attachment.download": "Télécharger",
"file_info_preview.size": "Taille ",
@@ -1307,7 +1309,7 @@
"filtered_user_list.countTotalPage": "{startCount, number} - {endCount, number} {count, plural, =0 {0 members} one {member} other {members}} of {total} au total",
"filtered_user_list.member": "Membre",
"filtered_user_list.next": "Suivant",
- "filtered_user_list.prev": "Previous",
+ "filtered_user_list.prev": "Précédent",
"filtered_user_list.search": "Rechercher des utilisateurs",
"filtered_user_list.searchButton": "Rechercher",
"filtered_user_list.show": "Filtre :",
@@ -1321,13 +1323,13 @@
"find_team.submitError": "Veuillez spécifier une adresse e-mail valide",
"flag_post.flag": "Marquez le message d'un indicateur pour le suivi",
"flag_post.unflag": "Supprimer l'indicateur",
- "general_tab.chooseDescription": "Choisissez un nom pour votre équipe",
+ "general_tab.chooseDescription": "Veuillez choisir une nouvelle description pour votre équipe",
"general_tab.chooseName": "Choisissez un nom pour votre équipe",
"general_tab.codeDesc": "Veuillez cliquer sur 'Modifier' pour réinitialiser le code d'invitation",
- "general_tab.codeLongDesc": "Le code d'invitation est utilisé dans l'URL contenant l'invitation à votre équipe créé depuis le menu principal grâce à <strong>Obtenir un lien d’invitation d’équipe</strong>. Regénérer cette clé rend toutes les invitations déjà envoyées invalide.",
+ "general_tab.codeLongDesc": "Le code d'invitation est utilisé dans l'URL du lien d'invitation à l'équipe. Ce lien est créé par {getTeamInviteLink} depuis le menu principal. Regénérer un nouveau lien d'invitation invalidera les invitations déjà envoyées.",
"general_tab.codeTitle": "Code d'invitation",
"general_tab.emptyDescription": "Veuillez cliquer sur 'Modifier' pour ajouter une description d'équipe.",
- "general_tab.getTeamInviteLink": "Créer une d'invitation",
+ "general_tab.getTeamInviteLink": "Créer un lien d'invitation",
"general_tab.includeDirDesc": "Inclure cette équipe affichera le nom de l'équipe dans l'annuaire sur la page d'accueil, ainsi qu'un lien pour rejoindre cette équipe.",
"general_tab.no": "Non",
"general_tab.openInviteDesc": "Lorsque autorisé, un lien vers cette équipe sera inclus sur la page d'accueil permettant à quiconque avec un compte de rejoindre cette équipe.",
@@ -1360,7 +1362,7 @@
"get_team_invite_link_modal.helpDisabled": "La création d'utilisateurs est désactivée pour votre équipe. Veuillez contacter votre administrateur système.",
"get_team_invite_link_modal.title": "Lien d'invitation à l'équipe",
"help.attaching.downloading": "#### Téléchargement de fichiers\nTéléchargez un fichier joint en cliquant sur l'icône de téléchargement à côté de la miniature de fichier ou en ouvrant l'aperçu du fichier et en cliquant sur **Télécharger**.",
- "help.attaching.dragdrop": "#### Glisser-déposer\nEnvoyez un fichier ou une sélection de fichiers en glissant les fichiers de votre ordinateur vers la barre latérale à droite ou dans le panneau central. Glisser-déposer un fichier l'attache à la zone de saisie. Vous pouvez alors optionnellement envoyer un message et presser **ENTREE** pour envoyer.",
+ "help.attaching.dragdrop": "#### Glisser-déposer\nEnvoyez un fichier ou une sélection de fichiers en glissant les fichiers de votre ordinateur vers la barre latérale à droite ou dans le panneau central. Glisser-déposer un fichier l'attache à la zone de saisie. Vous pouvez alors optionnellement tapper un message et appuyer sur **ENTREE** pour l'envoyer.",
"help.attaching.icon": "#### Icône de pièce jointe\nVous pouvez également envoyer des fichiers en cliquant sur l'icône grise représentant une trombone dans la zone de saisie du message. Une boîte de dialogue affichant vos fichiers locaux s'ouvrira alors, vous permettant de sélectionner les fichiers que vous souhaitez envoyer. Cliquez ensuite sur **Ouvrir** pour envoyer les fichiers dans la zone de saisie. Saisissez optionnellement un message et appuyez sur **Entrée** pour envoyer.",
"help.attaching.limitations": "## Limitations De Taille De Fichier\nMattermost prend en charge un maximum de cinq fichiers joints par poste, chacun avec une taille maximale de 50Mo.",
"help.attaching.methods": "## Méthodes d'envoi de pièces jointes\nEnvoyez un fichier joint en effectuant un glisser-déposer ou en cliquant sur l'icône de pièce jointe dans la zone de saisie du message.",
@@ -1381,7 +1383,7 @@
"help.composing.deleting": "## Suppression d'un message\nSupprimez un message en cliquant sur l'icône **[...]** située à côté de chaque message que vous avez saisi, puis cliquez sur **Supprimer**. Les administrateurs système et d'équipe peuvent supprimer n'importe quel message du système ou de l'équipe.",
"help.composing.editing": "## Edition d'un message\nEditez un message en cliquant sur l'icône **[...]** située à côté de chaque message que vous avez saisi, puis cliquez sur **Editer**. Après avoir effectué des modifications au message, appuyez sur **ENTREE** pour sauvegarder les modifications. Les éditions de messages ne déclenchent pas de nouvelles notifications de @mention, ni de notifications sur le bureau ni de sons de notifications.",
"help.composing.linking": "## Lien vers un message\nLa fonctionnalité de lien permanent permet de créer un lien vers n'importe quel message. Partager ce lien avec d'autres utilisateurs du canal permet à ces utilisateurs du canal de voir le message lié dans les Messages Archivés. Les utilisateurs qui ne sont pas membres du canal à partir duquel le message a été envoyé ne peuvent pas voir le lien permanent. Obtenez le lien vers un message en cliquant sur l'icône **[...]** située à côté de chaque message, > **Lien permanent** > **Copier le lien**.",
- "help.composing.posting": "## Envoi d'un message\nÉcrivez un message en tapant dans la zone de saisie de texte, puis appuyez sur **ENTREE** pour l'envoyer. Utilisez la combinaison **MAJ + ENTREE** pour insérer une nouvelle ligne sans envoyer le message. Pour envoyer des messages en utilisant sur **CTRL + ENTREE**, allez dans **Menu principal > Paramètres du compte > Envoi de messages avec CTRL + ENTREE**.",
+ "help.composing.posting": "## Envoi d'un message\nÉcrivez un message en tapant dans la zone de saisie de texte, puis appuyez sur ENTREE pour l'envoyer. Utilisez la combinaison MAJ + ENTREE pour insérer une nouvelle ligne sans envoyer le message. Pour envoyer des messages en utilisant sur CTRL + ENTREE, allez dans **Menu principal > Paramètres du compte > Envoi de messages avec CTRL + ENTREE**.",
"help.composing.posts": "#### Envois\nLes envois sont souvent considérés comme des messages parents. Ce sont les messages qui commencent souvent un fil de réponses. Les envois sont composés et envoyés à partir de la zone de saisie de texte en bas du panneau central.",
"help.composing.replies": "#### Réponses\nRépondez à un message en cliquant sur l'icône de réponse à côté de n'importe quel message de texte. Cette action ouvre la barre latérale de droite où vous pouvez voir le fil de messages, puis composer et envoyer votre réponse. Les réponses sont décalées légèrement dans le panneau central pour indiquer qu'elles sont les messages enfants d'un message parent.\n\nLorsque vous composez une réponse dans la barre latérale de droite, cliquez sur l'icône agrandir/réduire avec deux flèches, au-dessus de la barre latérale, de façon à rendre la vue plus facile à lire.",
"help.composing.title": "# Envoi de messages\n_____",
@@ -1395,7 +1397,7 @@
"help.formatting.example": "Exemple :",
"help.formatting.githubTheme": "**Thèmes GitHub**",
"help.formatting.headings": "## Titres\n\nCréez un titre en ajoutant # et un espace avant votre titre. Pour des titres de plus bas niveau, ajoutez plus de #.",
- "help.formatting.headings2": "Alternativement, vous pouvez souligner le texte à l'aide de `===` ou `---` pour créer des en-têtes.",
+ "help.formatting.headings2": "Alternativement, vous pouvez souligner le texte à l'aide de `===` ou `---` pour créer des entêtes.",
"help.formatting.headings2Example": "Grand en tête\n-------------",
"help.formatting.headingsExample": "## Grand en tête\n### Plus petit en tête\n#### Encore plus petit en tête",
"help.formatting.images": "## Images intégrées au message\n\nCréez des images intégrées au message en utilisant `!`suivi par le texte alternatif placé entre crochets et le lien placé entre parenthèses. Pour ajouter un texte apparaissant au survol de la souris, placez-le entre guillemets après le lien.",
@@ -1433,7 +1435,7 @@
"help.mentioning.channel": "#### @Channel\nVous pouvez mentionner tout un canal en écrivant `@channel`. Tous les membres du canal recevront une notification de mention qui se comporte de la même manière que si chacun avait été mentionné directement.",
"help.mentioning.channelExample": "@canal bon travail sur les entretiens cette semaine. Je pense que nous avons trouvé quelques excellents candidats potentiels !",
"help.mentioning.mentions": "## @Mentions\nUtiliser les @mentions pour attirer l'attention de certains membres de l'équipe.",
- "help.mentioning.recent": "## Mentions récentes\nCliquez sur `@` à côté de la barre de recherche pour rechercher vos @mentions récentes et les mots qui déclenchent les mentions. Cliquez sur **Lien (jump)** à côté d'un résultat de recherche dans le menu vertical à droite pour faire positionner le panneau central sur le canal et la position du message contenant la mention.",
+ "help.mentioning.recent": "## Mentions récentes\nCliquez sur `@` à côté de la barre de recherche pour rechercher vos @mentions récentes et les mots qui déclenchent les mentions. Cliquez sur **Aller à** à côté d'un résultat de recherche dans la barre latérale de droite pour faire positionner le panneau central sur le canal et l'endroit du message contenant la mention.",
"help.mentioning.title": "# Mentionnant Coéquipiers\n_____",
"help.mentioning.triggers": "## Mots qui déclenchent des mentions\nEn plus d'être notifié par @nom d'utilisateur et @cannal, vous pouvez personnaliser des mots qui déclenchent des notifications de mention dans **Paramètres du compte** > **Notifications** > **Mots qui déclenchent des mentions**. Par défaut, vous recevrez des notifications de mention sur base de votre prénom, mais vous pouvez ajouter davantage de mots en les tapant, séparés par des virgules, dans la zone de saisie. Ceci est utile si vous souhaitez être notifiés de tous les messages qui concernent certains sujets, par exemple, “interviewing” ou “marketing”.",
"help.mentioning.username": "#### @Nom d'utilisateur\nVous pouvez mentionner un coéquipier en utilisant le symbole `@` suivi de son nom d'utilisateur pour lui envoyer une notification de mention.\n\nTapez `@` pour afficher une liste des membres de l'équipe qui peuvent être mentionnés. Pour filtrer la liste, tapez les premières lettres de n'importe quel nom d'utilisateur, prénom, nom de famille, ou surnom. Les flèches du clavier **Haut** et **Bas** peuvent être utilisées pour faire défiler les différentes entrées dans la liste; la touche **Entrée** une fois appuyée sélectionnera l'utilisateur à mentionner. Une fois sélectionné, le nom d'utilisateur va automatiquement remplacer le nom et prénom ou le surnom.\nL'exemple suivant envoie une notification spéciale de mention à **alice** qui l'alerte du canal et du message dans laquelle elle a été citée. Si **alice** est absente de Mattermost et qu'elle a activé les [notifications par e-mail](http://docs.mattermost.com/help/getting-started/configuring-notifications.html#email-notifications), alors elle recevra une alerte par e-mail de sa mention accompagnée du message texte concerné par cette mention.",
@@ -1445,10 +1447,10 @@
"help.messaging.notify": "**Avertissez vos coéquipiers** lorsque nécessaire en tapant `@nom d'utilisateur`.",
"help.messaging.reply": "**Répondez aux messages** en cliquant sur la flèche de réponse à côté du texte du message.",
"help.messaging.title": "# Messagerie de base\n_____",
- "help.messaging.write": "**Ecrivez des messages** en utilisant la zone de saisie en bas de l'interface de Mattermost. Appuyez sur **ENTREE** pour envoyer un message. Utilisez *Maj+ENTREE** pour effectuer un retour à la ligne sans envoyer le message.",
+ "help.messaging.write": "**Ecrivez des messages** en utilisant la zone de saisie en bas de l'interface de Mattermost. Appuyez sur ENTREE pour envoyer un message. Utilisez MAJ + ENTREE pour effectuer un retour à la ligne sans envoyer le message.",
"installed_command.header": "Commandes Slash",
"installed_commands.add": "Ajout de la commande Slash",
- "installed_commands.delete.confirm": "This action permanently deletes the slash command and breaks any integrations using it. Are you sure you want to delete it?",
+ "installed_commands.delete.confirm": "Cette action supprime définitivement la commande slash et casse toutes les intégrations qui l'utilisent. Voulez-vous vraiment la supprimer ?",
"installed_commands.empty": "Pas de commande trouvée",
"installed_commands.header": "Commande Slash",
"installed_commands.help": "Créez des commandes slash pour les intégrations externes. Vous pouvez consulter la documentation {link}.",
@@ -1456,7 +1458,7 @@
"installed_commands.search": "Rechercher les commandes slash",
"installed_commands.unnamed_command": "Commande slash sans nom",
"installed_incoming_webhooks.add": "Ajouter des Webhooks entrants",
- "installed_incoming_webhooks.delete.confirm": "This action permanently deletes the incoming webhook and breaks any integrations using it. Are you sure you want to delete it?",
+ "installed_incoming_webhooks.delete.confirm": "Cette action supprime définitivement le webhook entrant et casse toutes les intégrations qui l'utilisent. Voulez-vous vraiment le supprimer ?",
"installed_incoming_webhooks.empty": "Aucun webhooks entrants trouvés",
"installed_incoming_webhooks.header": "Webhooks entrants",
"installed_incoming_webhooks.help": "Créer des webhooks entrants pour vos intégrations externes. Vous pouvez consulter la documentation {link}.",
@@ -1482,7 +1484,7 @@
"installed_oauth_apps.add": "Ajouter une application OAuth 2.0",
"installed_oauth_apps.callbackUrls": "URLs de callback (une par ligne)",
"installed_oauth_apps.cancel": "Annuler",
- "installed_oauth_apps.delete.confirm": "This action permanently deletes the OAuth 2.0 application and breaks any integrations using it. Are you sure you want to delete it?",
+ "installed_oauth_apps.delete.confirm": "Cette action supprime définitivement l'application OAuth 2.0 et casse toutes les intégrations qui l'utilisent. Voulez-vous vraiment le supprimer ?",
"installed_oauth_apps.description": "Description",
"installed_oauth_apps.empty": "Pas d'applications OAuth 2.0 trouvées",
"installed_oauth_apps.header": "Applications OAuth 2.0",
@@ -1498,7 +1500,7 @@
"installed_oauth_apps.trusted.no": "Non",
"installed_oauth_apps.trusted.yes": "Oui",
"installed_outgoing_webhooks.add": "Ajouter des Webhooks sortants",
- "installed_outgoing_webhooks.delete.confirm": "This action permanently deletes the outgoing webhook and breaks any integrations using it. Are you sure you want to delete it?",
+ "installed_outgoing_webhooks.delete.confirm": "Cette action supprime définitivement le webhook sortant et casse toutes les intégrations qui l'utilisent. Voulez-vous vraiment le supprimer ?",
"installed_outgoing_webhooks.empty": "Aucun webhooks sortants trouvés",
"installed_outgoing_webhooks.header": "Webhooks sortants",
"installed_outgoing_webhooks.help": "Créer des webhooks sortants pour vos intégrations externes. Vous pouvez consulter la documentation {link}.",
@@ -1509,7 +1511,7 @@
"integrations.command.description": "Les commandes Slash envoient des évènements à des intégrations extérieures",
"integrations.command.title": "Commande Slash",
"integrations.delete.confirm.button": "Supprimer",
- "integrations.delete.confirm.title": "Delete Integration",
+ "integrations.delete.confirm.title": "Supprimer l'intégration",
"integrations.done": "Effectué",
"integrations.edit": "Modifier",
"integrations.header": "Intégrations",
@@ -1533,7 +1535,7 @@
"intro_messages.offTopic": "<h4 class=\"channel-intro__title\">Début de {display_name}</h4><p class=\"channel-intro__content\">Ceci est le début de {display_name}, un canal destiné aux conversations extra-professionnelles.<br/></p>",
"intro_messages.onlyInvited": " Seuls les membres invités peuvent voir ce groupe privé.",
"intro_messages.purpose": " L'objectif de {type} est : {purpose}.",
- "intro_messages.setHeader": "Définir l'en-tête",
+ "intro_messages.setHeader": "Définit l'entête",
"intro_messages.teammate": "Vous êtes au début de votre historique de messages avec cet utilisateur. Les messages privés et les fichiers partagés ici ne sont pas visibles par les autres utilisateurs.",
"invite_member.addAnother": "Ajouter un autre",
"invite_member.autoJoin": "Les membres automatiquement invités rejoignent le canal <strong>{channel}</strong>.",
@@ -1591,7 +1593,7 @@
"login.passwordChanged": " Mot de passe mis a jour avec succès",
"login.session_expired": " Votre session a expiré. Merci de vous reconnecter.",
"login.signIn": "Connexion",
- "login.signInLoading": "Signing in...",
+ "login.signInLoading": "Authentification en cours...",
"login.signInWith": "Se connecter avec:",
"login.userNotFound": "Nous ne trouvons aucun compte correspondants a vos identifiants de connexions.",
"login.username": "Nom d'utilisateur",
@@ -1635,30 +1637,30 @@
"more_channels.join": "Rejoindre",
"more_channels.next": "Suivant",
"more_channels.noMore": "Il n'y a plus d'autre canal que vous pouvez rejoindre",
- "more_channels.prev": "Previous",
+ "more_channels.prev": "Précédent",
"more_channels.title": "Plus de canaux",
"more_direct_channels.close": "Fermer",
"more_direct_channels.message": "Message",
- "more_direct_channels.new_convo_note": "This will start a new conversation. If you’re adding a lot of people, consider creating a private group instead.",
- "more_direct_channels.new_convo_note.full": "You’ve reached the maximum number of people for this conversation. Consider creating a private group instead.",
+ "more_direct_channels.new_convo_note": "Ceci va démarrer une nouvelle conversation. Si vous ajoutez beaucoup de personnes, veuillez envisager la création d'un groupe privé à la place.",
+ "more_direct_channels.new_convo_note.full": "Vous avez atteint le nombre maximum de personnes pour cette conversation. Veuillez envisager la création d'un groupe privé à la place.",
"more_direct_channels.title": "Messages privés",
"msg_typing.areTyping": "{users} et {last} sont en train d'écrire...",
"msg_typing.isTyping": "{user} est en train d'écrire...",
"msg_typing.someone": "Quelqu'un",
- "multiselect.go": "Go",
- "multiselect.instructions": "Use up/down arrows to navigate and enter to select",
- "multiselect.numPeopleRemaining": "You can add {num, number} more {num, plural, =0 {people} one {person} other {people}}. ",
- "multiselect.numRemaining": "You can add {num, number} more",
- "multiselect.placeholder": "Search and add members",
+ "multiselect.go": "Aller à",
+ "multiselect.instructions": "Utiliser les flèches haut/bas pour naviguer et la touche enter pour sélectionner",
+ "multiselect.numPeopleRemaining": "Vous pouvez encore ajouter {num, number} en plus {num, plural, =0 {people} une {person} autre {people}}. ",
+ "multiselect.numRemaining": "Vous pouvez encore en ajouter {num, number} en plus",
+ "multiselect.placeholder": "Rechercher et ajouter des membres",
"navbar.addMembers": "Ajouter Membres",
"navbar.click": "Cliquez ici",
"navbar.delete": "Supprimer le canal...",
"navbar.leave": "Quitter le canal",
"navbar.manageMembers": "Gérer les membres",
- "navbar.noHeader": "Pas encore d'en-tête de canal.{newline}{link} pour en ajouter une.",
+ "navbar.noHeader": "Aucun entête de canal encore défini.{newline}{link} pour en ajouter un.",
"navbar.preferences": "Préférences de notifications",
"navbar.rename": "Renommer le canal...",
- "navbar.setHeader": "Définir l'en-tête du canal...",
+ "navbar.setHeader": "Définir l'entête du canal...",
"navbar.setPurpose": "Définir la description du canal...",
"navbar.toggle1": "Basculer la barre latérale",
"navbar.toggle2": "Basculer la barre latérale",
@@ -1670,16 +1672,16 @@
"navbar_dropdown.emoji": "Emoji personnalisés",
"navbar_dropdown.help": "Aide",
"navbar_dropdown.integrations": "Intégrations",
- "navbar_dropdown.inviteMember": "Inviter un nouveau membre",
+ "navbar_dropdown.inviteMember": "Inviter un membre",
"navbar_dropdown.join": "Rejoindre une autre équipe",
"navbar_dropdown.leave": "Quitter l'équipe",
"navbar_dropdown.logout": "Se déconnecter",
"navbar_dropdown.manageMembers": "Gérer les membres",
- "navbar_dropdown.nativeApps": "Télécharger les applications",
+ "navbar_dropdown.nativeApps": "Télécharger les apps",
"navbar_dropdown.report": "Signaler un problème",
"navbar_dropdown.switchTeam": "Basculer sur {team}",
"navbar_dropdown.switchTo": "Basculer vers ",
- "navbar_dropdown.teamLink": "Créer une d'invitation",
+ "navbar_dropdown.teamLink": "Créer une invitation",
"navbar_dropdown.teamSettings": "Configuration de l'équipe",
"navbar_dropdown.viewMembers": "Voir les membres",
"notification.dm": "Message privé",
@@ -1718,11 +1720,11 @@
"post_info.mobile.unflag": "Supprimer l'indicateur",
"post_info.permalink": "Lien permanent",
"post_info.reply": "Répondre",
- "post_info.system": "System",
- "post_message_view.edited": "(edited)",
+ "post_info.system": "Système",
+ "post_message_view.edited": "(édité)",
"posts_view.loadMore": "Charger plus de messages",
"posts_view.newMsg": "Nouveaux messages",
- "posts_view.newMsgBelow": "Nouveau {count, plural, one {message} other {messages}} dessous",
+ "posts_view.newMsgBelow": "{count, plural, one {Nouveau message} other {Nouveaux messages}} ci-dessous",
"reaction.clickToAdd": "(cliquez pour ajouter)",
"reaction.clickToRemove": "(cliquez pour supprimer)",
"reaction.othersReacted": "{otherUsers, number} {otherUsers, plural, one {user} other {users}}",
@@ -1743,13 +1745,13 @@
"rename_channel.defaultError": " - Ne peut être changé en canal par défaut",
"rename_channel.displayName": "Nom d'affichage",
"rename_channel.displayNameHolder": "Saisissez le nom d'affichage",
- "rename_channel.handleHolder": "Doit être en caractères alphanumériques minuscules",
+ "rename_channel.handleHolder": "caractères alphanumériques minuscules",
"rename_channel.lowercase": "Doit être en caractères alphanumériques minuscules",
"rename_channel.maxLength": "Ce champ doit faire moins de 22 caractères",
"rename_channel.required": "Ce champ est obligatoire",
"rename_channel.save": "Enregistrer",
"rename_channel.title": "Renommer le canal",
- "rename_channel.url": "URL :",
+ "rename_channel.url": "URL",
"rhs_comment.comment": "Commentaire",
"rhs_comment.del": "Supprimer",
"rhs_comment.edit": "Éditer",
@@ -1777,7 +1779,7 @@
"search_header.title2": "Mentions récentes",
"search_header.title3": "Messages marqués d'un indicateur",
"search_item.direct": "Message privé (avec {username})",
- "search_item.jump": "Lien (jump)",
+ "search_item.jump": "Aller à",
"search_results.because": "<ul><li>Pour rechercher une partie d'un mot (ex. rechercher \"réa\" en souhaitant \"réagir\" ou \"réaction\"), ajoutez un * au terme recherché</li><li>En raison du nombre de résultats, les recherches sur deux lettres ou sur les mots communs tels que \"ce\", \"un\" et \"est\" n'apparaîtront pas dans les résultats de la recherche</li></ul>",
"search_results.noResults": "Aucun résultat. Recommencer ?",
"search_results.usage": "<ul><li>Utilisez <b>\"des guillemets\"</b> pour rechercher des phrases</li><li>Utilisez <b>from:</b> pour rechercher des messages d'utilisateurs spécifiques et <b>in:</b> pour rechercher des messages sur des canaux spécifiques</li></ul>",
@@ -1807,7 +1809,7 @@
"sidebar.removeList": "Retirer de la liste",
"sidebar.tutorialScreen1": "<h4>Canaux</h4><p><strong>Les canaux</strong> organisent les conversations en sujets distincts. Ils sont ouverts à tous les utilisateurs de votre équipe. Pour envoyer des messages privés, utilisez <strong>Messages privés</strong> pour une personne ou <strong>Groupes privés</strong> pour plusieurs personnes.</p>",
"sidebar.tutorialScreen2": "<h4>Canaux \"{townsquare}\" et \"{offtopic}\"</h4><p>Voici deux canaux publics pour commencer :</p><p><strong>{townsquare}</strong> est l'endroit idéal pour communiquer avec toute l'équipe. Tous les membres de votre équipe sont membres de ce canal.</p><p><strong>{offtopic}</strong> (est l'endroit pour se détendre et parler d'autre chose que du travail. Vous et votre équipe décidez des autres canaux à créer.</p>",
- "sidebar.tutorialScreen3": "<h4>Créer et rejoindre des canaux</h4><p>Cliquez sur <strong>\"Plus...\"</strong> pour créer un nouveau canal ou rejoindre un canal existant.</p><p>Vous pouvez aussi créer un nouveau canal ou un groupe privé en cliquant sur le symbole <strong>\"+\"</strong> à côté du nom du canal ou de l'en-tête du groupe privé.</p>",
+ "sidebar.tutorialScreen3": "<h4>Créer et rejoindre des canaux</h4><p>Cliquez sur <strong>\"Plus...\"</strong> pour créer un nouveau canal ou rejoindre un canal existant.</p><p>Vous pouvez aussi créer un nouveau canal ou un groupe privé en cliquant sur le symbole <strong>\"+\"</strong> à côté du nom du canal ou de l'entête du groupe privé.</p>",
"sidebar.unreadAbove": "Message(s) non-lu(s) ci-dessus",
"sidebar.unreadBelow": "Message(s) non-lu(s) ci-dessous",
"sidebar_header.tutorial": "<h4>Menu principal</h4><p>Le <strong>Menu Principal</strong> est l'endroit où vous pouvez <strong>inviter des nouveaux membres</strong>, accéder aux <strong>paramètres de votre compte</strong> et configurer les <strong>couleurs de votre thème</strong>.</p><p>Les administrateurs d'équipe peuvent aussi accéder aux <strong>paramètres de l'équipe</strong>.</p><p>Les administrateurs système trouveront la <strong>console système</strong> pour administrer tout le site.</p>",
@@ -1953,11 +1955,11 @@
"update_command.question": "Vos modifications peuvent casser la commande Slash existante. Voulez-vous vraiment la mettre à jour ?",
"update_command.update": "Mettre à jour",
"update_incoming_webhook.update": "Mettre à jour",
- "update_outgoing_webhook.confirm": "Ajouter des Webhooks sortants",
- "update_outgoing_webhook.question": "Vos modifications peuvent casser la commande Slash existante. Voulez-vous vraiment la mettre à jour ?",
+ "update_outgoing_webhook.confirm": "Editer les Webhooks sortants",
+ "update_outgoing_webhook.question": "Vos modifications peuvent casser le webhook sortant existant. Voulez-vous vraiment le mettre à jour ?",
"update_outgoing_webhook.update": "Mettre à jour",
"upload_overlay.info": "Faites glisser un fichier pour le télécharger.",
- "user.settings.advance.embed_preview": "For the first web link in a message, display a preview of website content below the message, if available",
+ "user.settings.advance.embed_preview": "Pour le premier lien web dans un message, afficher un aperçu du contenu du site sous le message, si disponible.",
"user.settings.advance.embed_toggle": "Voir un aperçu pour tous les messages inclus",
"user.settings.advance.enabledFeatures": "{count, number} {count, plural, one {Feature} other {Features}} Activée",
"user.settings.advance.formattingDesc": "Si activé, les messages seront formatés pour créer des liens, montrer des emoji, le style du texte et ajouter des sauts de ligne. Par défaut, ce paramètre est activé. La modification de ce paramètre nécessite le rafraîchissement de la page.",
@@ -1969,43 +1971,43 @@
"user.settings.advance.on": "Activé",
"user.settings.advance.preReleaseDesc": "Évaluez les fonctionnalités en avant-première. Vous devrez peut-être rafraîchir la page pour que ce paramètre soit activé.",
"user.settings.advance.preReleaseTitle": "Activer les fonctionnalités expérimentales",
- "user.settings.advance.sendDesc": "Si activé, 'Entrée' insère une nouvelle ligne et 'Ctrl + Entrée' envoie le message.",
- "user.settings.advance.sendTitle": "Envoyer vos messages avec Ctrl+Entrée",
+ "user.settings.advance.sendDesc": "Si activé, ENTREE insère une nouvelle ligne et CTRL + ENTREE envoie le message.",
+ "user.settings.advance.sendTitle": "Envoyer vos messages avec CTRL + ENTREE",
"user.settings.advance.slashCmd_autocmp": "Autoriser les applications externes à proposer l'auto-complétion des commandes slash",
"user.settings.advance.title": "Paramètres avancés",
"user.settings.advance.webrtc_preview": "Activer la possibilité de passer et de recevoir des appels WebRTC en tête-à-tête",
"user.settings.custom_theme.awayIndicator": "Indicateur \"absent\"",
- "user.settings.custom_theme.buttonBg": "Fond de bouton",
+ "user.settings.custom_theme.buttonBg": "Arrière-plan du bouton",
"user.settings.custom_theme.buttonColor": "Texte de bouton",
- "user.settings.custom_theme.centerChannelBg": "Fond de l'espace central",
+ "user.settings.custom_theme.centerChannelBg": "Arrière-plan de l'espace central",
"user.settings.custom_theme.centerChannelColor": "Text du canal central",
"user.settings.custom_theme.centerChannelTitle": "Styles de l'espace central",
"user.settings.custom_theme.codeTheme": "Code du thème",
"user.settings.custom_theme.copyPaste": "Copiez/Collez pour partager les couleurs du thème :",
"user.settings.custom_theme.linkButtonTitle": "Styles des boutons et liens",
"user.settings.custom_theme.linkColor": "Couleur de lien",
- "user.settings.custom_theme.mentionBj": "Arrière-plan bulle de mention",
+ "user.settings.custom_theme.mentionBj": "Arrière-plan de la bulle de mention",
"user.settings.custom_theme.mentionColor": "Texte bulle de mention",
- "user.settings.custom_theme.mentionHighlightBg": "Fond de la mise en surbrillance lors d'une mention",
+ "user.settings.custom_theme.mentionHighlightBg": "Arrière-plan de la mise en surbrillance lors d'une mention",
"user.settings.custom_theme.mentionHighlightLink": "Lien de mise en surbrillance lors d'une mention",
"user.settings.custom_theme.newMessageSeparator": "Séparateur de nouveau message",
"user.settings.custom_theme.onlineIndicator": "Indicateur \"connecté\"",
- "user.settings.custom_theme.sidebarBg": "Fond de barre latérale",
- "user.settings.custom_theme.sidebarHeaderBg": "Fond d'en-tête de barre latérale",
- "user.settings.custom_theme.sidebarHeaderTextColor": "Texte d'en-tête de barre latérale",
+ "user.settings.custom_theme.sidebarBg": "Arrière-plan de la barre latérale",
+ "user.settings.custom_theme.sidebarHeaderBg": "Arrière-plan de l'entête de la barre latérale",
+ "user.settings.custom_theme.sidebarHeaderTextColor": "Texte d'entête de la barre latérale",
"user.settings.custom_theme.sidebarText": "Texte de barre latérale",
"user.settings.custom_theme.sidebarTextActiveBorder": "Contour de texte de barre latéral actif",
"user.settings.custom_theme.sidebarTextActiveColor": "Text de barre latérale actif",
- "user.settings.custom_theme.sidebarTextHoverBg": "Fond de survol (hover) de barre latérale",
+ "user.settings.custom_theme.sidebarTextHoverBg": "Arrière-plan lors du survol de la barre latérale",
"user.settings.custom_theme.sidebarTitle": "Style des barres latérales",
"user.settings.custom_theme.sidebarUnreadText": "Texte non-lu de barre latérale",
"user.settings.display.channelDisplayTitle": "Mode d’affichage du canal",
"user.settings.display.channeldisplaymode": "Veuillez spécifier la largeur de l'espace central.",
"user.settings.display.clockDisplay": "Affichage de l'horloge",
- "user.settings.display.collapseDesc": "Set whether previews of image links show as expanded or collapsed by default. This setting can also be controlled using the slash commands /expand and /collapse.",
- "user.settings.display.collapseDisplay": "Default appearance of image link previews",
- "user.settings.display.collapseOff": "Collapsed",
- "user.settings.display.collapseOn": "Expanded",
+ "user.settings.display.collapseDesc": "Définit si les aperçus de liens d'images s'affichent étendus ou réduits par défaut. Ce paramètre peut également être contrôlé à l'aide des commandes slash /expand et /collapse.",
+ "user.settings.display.collapseDisplay": "Apparence par défaut des aperçus de liens d'images",
+ "user.settings.display.collapseOff": "Réduit",
+ "user.settings.display.collapseOn": "Etendu",
"user.settings.display.fixedWidthCentered": "Largeur fixe, centré",
"user.settings.display.fontDesc": "Choisissez la police de caractères utilisée pour l'interface de Mattermost.",
"user.settings.display.fontTitle": "Police d'affichage",
@@ -2145,7 +2147,7 @@
"user.settings.notifications.emailNotifications": "Notifications par e-mail",
"user.settings.notifications.header": "Notifications",
"user.settings.notifications.info": "Les notifications de bureau sont disponibles sur Edge, Firefox, Safari, Chrome et les applications desktop Mattermost.",
- "user.settings.notifications.mentionsInfo": "Mentions trigger when someone sends a message that includes your username (\"@{username}\") or any of the options selected above.",
+ "user.settings.notifications.mentionsInfo": "Les mentions se déclenchent lorsque quelqu'un envoie un message qui inclut votre nom d'utilisateur (\"@{username}\") ou l'une des options ci-dessus.",
"user.settings.notifications.never": "Jamais",
"user.settings.notifications.noWords": "Aucun mot configuré",
"user.settings.notifications.off": "Désactivé",
@@ -2189,9 +2191,9 @@
"user.settings.security.lastUpdated": "Dernière mise à jour le {date} à {time}",
"user.settings.security.ldap": "AD/LDAP",
"user.settings.security.loginGitlab": "Connexion avec GitLab",
- "user.settings.security.loginGoogle": "Login done through Google Apps",
+ "user.settings.security.loginGoogle": "Connexion à partir de Google Apps",
"user.settings.security.loginLdap": "Connexion avec LDAP",
- "user.settings.security.loginOffice365": "Login done through Office 365",
+ "user.settings.security.loginOffice365": "Connexion à partir d'Office 365",
"user.settings.security.loginSaml": "Se connecter par SAML",
"user.settings.security.logoutActiveSessions": "Consulter et déconnecter les sessions actives",
"user.settings.security.method": "Méthode de connexion",
@@ -2199,7 +2201,7 @@
"user.settings.security.noApps": "Aucune application OAuth 2.0 autorisée.",
"user.settings.security.oauthApps": "Applications OAuth 2.0",
"user.settings.security.oauthAppsDescription": "Veuillez cliquer sur 'Modifier' pour gérer vos applications OAuth 2.0",
- "user.settings.security.oauthAppsHelp": "Les applications agissent en votre nom pour accéder à vos données sur la base des autorisations que vous leur accordez.",
+ "user.settings.security.oauthAppsHelp": "Les applications agissent en votre nom pour accéder à vos données sur base des permissions que vous leur accordez.",
"user.settings.security.office365": "Office 365",
"user.settings.security.oneSignin": "Vous ne pouvez avoir qu'une seule méthode de connexion à la fois. Changer de méthode de connexion provoquera l'envoi d'un e-mail vous notifiant que le changement a réussi.",
"user.settings.security.password": "Mot de passe",
@@ -2220,11 +2222,11 @@
"user.settings.security.passwordErrorUppercaseNumberSymbol": "Votre mot de passe doit contenir au moins {min} caractères et au moins une lettre majuscule, un chiffre et un symbole (parmi \"~!@#$%^&*()\").",
"user.settings.security.passwordErrorUppercaseSymbol": "Votre mot de passe doit contenir au moins {min} caractères et au moins une lettre majuscule et un symbole (parmi \"~!@#$%^&*()\").",
"user.settings.security.passwordGitlabCantUpdate": "La connexion se produit à travers GitLab. Le mot de passe ne peut pas être mis à jour.",
- "user.settings.security.passwordGoogleCantUpdate": "La connexion se produit à travers GitLab. Le mot de passe ne peut pas être mis à jour.",
+ "user.settings.security.passwordGoogleCantUpdate": "La connexion s'effectue par Google Apps. Le mot de passe ne peut pas être mis à jour.",
"user.settings.security.passwordLdapCantUpdate": "La connexion se produit via LDAP . Le mot de passe ne peut pas être mis à jour.",
"user.settings.security.passwordMatchError": "Les nouveaux mots de passe que vous avez saisis ne correspondent pas.",
"user.settings.security.passwordMinLength": "Longueur minimum invalide, impossible d'afficher l'aperçu.",
- "user.settings.security.passwordOffice365CantUpdate": "La connexion se produit à travers GitLab. Le mot de passe ne peut pas être mis à jour.",
+ "user.settings.security.passwordOffice365CantUpdate": "La connexion s'effectue par Office 365. Le mot de passe ne peut pas être mis à jour.",
"user.settings.security.passwordSamlCantUpdate": "Ce champ est géré par le service d'authentification. Si vous souhaitez le modifier, vous devez le faire par le biais de votre service d'authentification.",
"user.settings.security.retypePassword": "Répéter le nouveau mot de passe",
"user.settings.security.saml": "SAML",
diff --git a/webapp/i18n/i18n.jsx b/webapp/i18n/i18n.jsx
index 4eda91198..fd4e42a32 100644
--- a/webapp/i18n/i18n.jsx
+++ b/webapp/i18n/i18n.jsx
@@ -9,8 +9,8 @@ const ko = require('!!file-loader?name=i18n/[name].[hash].[ext]!./ko.json');
const nl = require('!!file-loader?name=i18n/[name].[hash].[ext]!./nl.json');
const pt_BR = require('!!file-loader?name=i18n/[name].[hash].[ext]!./pt-BR.json'); //eslint-disable-line camelcase
const ru = require('!!file-loader?name=i18n/[name].[hash].[ext]!./ru.json');
-const zh_TW = require('!!file-loader?name=i18n/[name].[hash].[ext]!./zh_TW.json'); //eslint-disable-line camelcase
-const zh_CN = require('!!file-loader?name=i18n/[name].[hash].[ext]!./zh_CN.json'); //eslint-disable-line camelcase
+const zh_TW = require('!!file-loader?name=i18n/[name].[hash].[ext]!./zh-TW.json'); //eslint-disable-line camelcase
+const zh_CN = require('!!file-loader?name=i18n/[name].[hash].[ext]!./zh-CN.json'); //eslint-disable-line camelcase
import {addLocaleData} from 'react-intl';
import deLocaleData from 'react-intl/locale-data/de';
diff --git a/webapp/i18n/ja.json b/webapp/i18n/ja.json
index f72af3026..da92f954e 100644
--- a/webapp/i18n/ja.json
+++ b/webapp/i18n/ja.json
@@ -217,8 +217,11 @@
"admin.customization.customEmoji": "カスタム絵文字",
"admin.customization.enableCustomEmojiDesc": "ユーザーがメッセージ中で使用するカスタム絵文字の作成を有効にします。有効にした場合、カスタム絵文字は、チームに切り替え、チャンネルのサイドバー3点マークをクリックして、「カスタム絵文字」を選択することで設定できます。",
"admin.customization.enableCustomEmojiTitle": "カスタム絵文字を有効にする:",
+ "admin.customization.enableLinkPreviewsDesc": "メッセージの下にウェブサイトのプレビューを表示するようにします。有効な場合、ウェブサイトのプレビューは アカウント設定 > 詳細 > プリリリース機能をプレビューする から設定できます。",
+ "admin.customization.enableLinkPreviewsTitle": "リンクのプレビューを有効にする:",
"admin.customization.iosAppDownloadLinkDesc": "iOSアプリのダウンロードリンクを追加してください。モバイル用ウェブブラウザーでサイトにアクセスしたユーザへ、アプリをダウンロードするか選択するページを表示します。空欄にした場合、そのページは表示されません。",
"admin.customization.iosAppDownloadLinkTitle": "iOSアプリダウンロード用リンク:",
+ "admin.customization.linkPreviews": "リンクのプレビュー",
"admin.customization.nativeAppLinks": "Mattermostアプリリンク",
"admin.customization.restrictCustomEmojiCreationAdmin": "システム管理者とチーム管理者にカスタム絵文字を作成できるようにする",
"admin.customization.restrictCustomEmojiCreationAll": "全員にカスタム絵文字を作成できるようにする",
@@ -764,6 +767,7 @@
"admin.sidebar.ldap": "AD/LDAP",
"admin.sidebar.legalAndSupport": "法的事項とサポート",
"admin.sidebar.license": "Editionとライセンス",
+ "admin.sidebar.linkPreviews": "リンクのプレビュー",
"admin.sidebar.localization": "言語",
"admin.sidebar.logging": "ログ",
"admin.sidebar.login": "ログイン",
@@ -935,8 +939,6 @@
"analytics.system.activeUsers": "投稿実績のあるアクティブユーザー",
"analytics.system.channelTypes": "チャンネル形式",
"analytics.system.dailyActiveUsers": "日次アクティブユーザー",
- "analytics.system.expiredBanner": "エンタープライズライセンスは{date}に期限が切れました。この日から15日以内にライセンスを更新してください。問い合わせは<a href='mailto:commercial@mattermost.com'>commercial@mattermost.com</a>までお願いします。",
- "analytics.system.expiringBanner": "エンタープライズライセンスは{date}に期限が切れます。ライセンスを更新するには、<a href='mailto:commercial@mattermost.com'>commercial@mattermost.com</a>に問い合わせてください。",
"analytics.system.monthlyActiveUsers": "月次アクティブユーザー",
"analytics.system.postTypes": "投稿、ファイル、ハッシュタグ",
"analytics.system.privateGroups": "非公開グループ",
@@ -1287,9 +1289,9 @@
"error.not_found.title": "ページが見つかりません",
"error.not_supported.message": "プライベートブラウジングはサポートされていません",
"error.not_supported.title": "ブラウザーはサポートされていません",
- "error_bar.expired": "エンタープライズライセンスは期限が切れました。期限切れの日から15日以内にライセンスを更新してください。問い合わせはcommercial@mattermost.comまでお願いします。",
- "error_bar.expiring": "エンタープライズライセンスは{date}に期限が切れます。ライセンスを更新するには、commercial@mattermost.comに問い合わせてください。",
- "error_bar.past_grace": "エンタープライズライセンスの期限が切れました。システム管理者に詳細を問い合わせてください。",
+ "error_bar.expired": "エンタープライズライセンスが期限切れのため、いくつかの機能が無効になります。<a href='{link}' target='_blank'>こちらから更新してください</a>。",
+ "error_bar.expiring": "エンタープライズライセンスは {date} に有効期限が切れました。<a href='{link}' target='_blank'>こちらから更新してください</a>。",
+ "error_bar.past_grace": "エンタープライズライセンスが期限切れのため、いくつかの機能が無効になります。詳細についてはシステム管理者に問い合わせてください。",
"error_bar.preview_mode": "プレビューモード: 電子メール通知は設定されていません",
"file_attachment.download": "ダウンロードする",
"file_info_preview.size": "サイズ ",
diff --git a/webapp/i18n/ko.json b/webapp/i18n/ko.json
index ae72b5f6f..aa668ed14 100644
--- a/webapp/i18n/ko.json
+++ b/webapp/i18n/ko.json
@@ -217,8 +217,11 @@
"admin.customization.customEmoji": "커스텀 이모티콘",
"admin.customization.enableCustomEmojiDesc": "Enable users to create custom emoji for use in messages. When enabled, Custom Emoji settings can be accessed by switching to a team and clicking the three dots above the channel sidebar, and selecting \"Custom Emoji\".",
"admin.customization.enableCustomEmojiTitle": "커스텀 이모티콘:",
+ "admin.customization.enableLinkPreviewsDesc": "Enable users to display a preview of website content below the message, if available. When true, website previews can be enabled from Account Settings > Advanced > Preview pre-release features.",
+ "admin.customization.enableLinkPreviewsTitle": "Enable Link Previews:",
"admin.customization.iosAppDownloadLinkDesc": "Add a link to download the iOS app. Users who access the site on a mobile web browser will be prompted with a page giving them the option to download the app. Leave this field blank to prevent the page from appearing.",
"admin.customization.iosAppDownloadLinkTitle": "iOS 앱 다운로드 링크:",
+ "admin.customization.linkPreviews": "링크 미리보기",
"admin.customization.nativeAppLinks": "Mattermost 애플리케이션 링크",
"admin.customization.restrictCustomEmojiCreationAdmin": "Allow System and Team Admins to create custom emoji",
"admin.customization.restrictCustomEmojiCreationAll": "Allow everyone to create custom emoji",
@@ -764,6 +767,7 @@
"admin.sidebar.ldap": "AD/LDAP",
"admin.sidebar.legalAndSupport": "지원",
"admin.sidebar.license": "라이센스와 에디션",
+ "admin.sidebar.linkPreviews": "링크 미리보기",
"admin.sidebar.localization": "지역화",
"admin.sidebar.logging": "로그",
"admin.sidebar.login": "로그인",
@@ -935,8 +939,6 @@
"analytics.system.activeUsers": "활성 사용자 (글 작성 기준)",
"analytics.system.channelTypes": "Channel Types",
"analytics.system.dailyActiveUsers": "Daily Active Users",
- "analytics.system.expiredBanner": "The Enterprise license expired on {date}. You have 15 days from this date to renew the license, please contact <a href='mailto:commercial@mattermost.com'>commercial@mattermost.com</a>.",
- "analytics.system.expiringBanner": "The Enterprise license is expiring on {date}. To renew your license, please contact <a href='mailto:commercial@mattermost.com'>commercial@mattermost.com</a>.",
"analytics.system.monthlyActiveUsers": "Monthly Active Users",
"analytics.system.postTypes": "글, 파일, 해시태그",
"analytics.system.privateGroups": "비공개 그룹",
@@ -1287,9 +1289,9 @@
"error.not_found.title": "페이지를 찾을 수 없습니다.",
"error.not_supported.message": "비밀모드는 지원되지 않습니다.",
"error.not_supported.title": "지원되지 않는 브라우저입니다.",
- "error_bar.expired": "엔터프라이즈 라이센스가 만료되었습니다; 15일 안에 라이센스를 갱신해야 합니다, 자세한 내용은 commercial@mattermost.com에 문의하세요.",
- "error_bar.expiring": "엔터프라이즈 라이센스가 {date}에 만료됩니다. 라이센스를 갱신하려면, commercial@mattermost.com에 문의하세요.",
- "error_bar.past_grace": "엔터프라이즈 라이센스가 만료되었습니다, 자세한 내용은 시스템 관리자에게 문의하세요.",
+ "error_bar.expired": "Enterprise license is expired and some features may be disabled. <a href='{link}' target='_blank'>Please renew.</a>",
+ "error_bar.expiring": "Enterprise license expires on {date}. <a href='{link}' target='_blank'>Please renew.</a>",
+ "error_bar.past_grace": "Enterprise license is expired and some features may be disabled. Please contact your System Administrator for details.",
"error_bar.preview_mode": "미리보기 모드: 이메일 알림이 설정되지 않았습니다.",
"file_attachment.download": "다운로드",
"file_info_preview.size": "용량 ",
diff --git a/webapp/i18n/nl.json b/webapp/i18n/nl.json
index 9c1178a4b..6af442227 100644
--- a/webapp/i18n/nl.json
+++ b/webapp/i18n/nl.json
@@ -217,8 +217,11 @@
"admin.customization.customEmoji": "Aangepaste emoji",
"admin.customization.enableCustomEmojiDesc": "Inschakelen dat gebruikers aangepaste emojis kunnen maken voor in berichten. Wanneer ingeschakeld, Aagepaste Emoji instellingen staan dan bij wisselen van team en dan op de drie puntjes klikken, en selecteer \"Aangepaste Emoji\".",
"admin.customization.enableCustomEmojiTitle": "Aangepaste emoji inschakelen:",
+ "admin.customization.enableLinkPreviewsDesc": "Enable users to display a preview of website content below the message, if available. When true, website previews can be enabled from Account Settings > Advanced > Preview pre-release features.",
+ "admin.customization.enableLinkPreviewsTitle": "Enable Link Previews:",
"admin.customization.iosAppDownloadLinkDesc": "Voeg een link toe naar de iOs app. Gebruikers die via een mobiele webbrowser de site bezoeken zullen een pagina krijgen met de optie om de app te downloaden. Laat dit veld leeg om deze pagina niet weer te geven. ",
"admin.customization.iosAppDownloadLinkTitle": "iOS App Download Link:",
+ "admin.customization.linkPreviews": "Link voorvertoningen",
"admin.customization.nativeAppLinks": "Mattermost App Links",
"admin.customization.restrictCustomEmojiCreationAdmin": "Sta Systeem en Team beheerders toe om aangepaste emojis te maken",
"admin.customization.restrictCustomEmojiCreationAll": "Iedereen toestaan aangepaste emoji te maken",
@@ -764,6 +767,7 @@
"admin.sidebar.ldap": "AD/LDAP",
"admin.sidebar.legalAndSupport": "Wettelijk en Ondersteuning",
"admin.sidebar.license": "Editie en Licentie",
+ "admin.sidebar.linkPreviews": "Link voorvertoningen",
"admin.sidebar.localization": "Lokalisatie",
"admin.sidebar.logging": "Loggen",
"admin.sidebar.login": "Login",
@@ -935,8 +939,6 @@
"analytics.system.activeUsers": "Actieve gebruikers met berichten",
"analytics.system.channelTypes": "Kanaal types",
"analytics.system.dailyActiveUsers": "Daily Active Users",
- "analytics.system.expiredBanner": "De Enterprise licentie is verlopen op {date}. U heeft 15 dagen vanaf deze datum om de licentie te vernieuwen. Neem contact op met <a href='mailto:commercial@mattermost.com'>commercial@mattermost.com</a>.",
- "analytics.system.expiringBanner": "De Enterprise licentie verloop op {date}. Om uw licentie te vernieuwen, neem contact op met <a href='mailto:commercial@mattermost.com'>commercial@mattermost.com</a>.",
"analytics.system.monthlyActiveUsers": "Monthly Active Users",
"analytics.system.postTypes": "Berichten, bestanden en hashtags",
"analytics.system.privateGroups": "Privé groepen",
@@ -1287,9 +1289,9 @@
"error.not_found.title": "Pagina niet gevonden",
"error.not_supported.message": "Browsen in \"privé modus\" is niet toegestaan.",
"error.not_supported.title": "Browser niet ondersteund",
- "error_bar.expired": "De Enterprise licentie is verlopen; u heeft 15 dagen om deze licentie te verlengen, neem contact op met commercial@mattermost.com voor details",
- "error_bar.expiring": "De Enterprise licentie zal verlopen op {date}. Voor het verlengen van uw licentie, kunt u contact opnemen met commercial@mattermost.com",
- "error_bar.past_grace": "De Enterprise licentie is verlopen, neem contact op met uw Systeembeheerder voor meer informatie",
+ "error_bar.expired": "Enterprise license is expired and some features may be disabled. <a href='{link}' target='_blank'>Please renew.</a>",
+ "error_bar.expiring": "Enterprise license expires on {date}. <a href='{link}' target='_blank'>Please renew.</a>",
+ "error_bar.past_grace": "Enterprise license is expired and some features may be disabled. Please contact your System Administrator for details.",
"error_bar.preview_mode": "Preview Modus: Email notificaties zijn niet geconfigureerd",
"file_attachment.download": "Downloaden",
"file_info_preview.size": "Grootte ",
diff --git a/webapp/i18n/pt-BR.json b/webapp/i18n/pt-BR.json
index 163a56d29..6b8ec4809 100644
--- a/webapp/i18n/pt-BR.json
+++ b/webapp/i18n/pt-BR.json
@@ -217,8 +217,11 @@
"admin.customization.customEmoji": "Emoji Personalizado",
"admin.customization.enableCustomEmojiDesc": "Habilitar para os usuários a criação de emoji personalizados para usar nas mensagens. Quando habilitado, as configurações dos Emoji personalizados podem ser acessadas trocando para Time e clicando nos três pontos encima do canal, e selecionando \"Emoji Personalizados\".",
"admin.customization.enableCustomEmojiTitle": "Ativar Emoji Personalizado:",
+ "admin.customization.enableLinkPreviewsDesc": "Permitir que os usuários exibam uma visualização do conteúdo do site abaixo da mensagem, se disponível. Quando verdadeiro, as pré-visualizações do site podem ser ativadas em Configurações da conta > Avançado > Visualizar recursos de pré-lançamento.",
+ "admin.customization.enableLinkPreviewsTitle": "Habilitar Visualizações de Links:",
"admin.customization.iosAppDownloadLinkDesc": "Adiciona um link para download do app iOS. Usuários que acessarem o site em um navegador móvel serão perguntados com uma página dando a opção para download do app. Deixe este campo em branco para evitar que a página apareça.",
"admin.customization.iosAppDownloadLinkTitle": "App iOS Link para Download:",
+ "admin.customization.linkPreviews": "Visualizações de Links",
"admin.customization.nativeAppLinks": "Links Aplicativo Mattermost",
"admin.customization.restrictCustomEmojiCreationAdmin": "Habilitar criação de emoji personalizados para Administradores de Sistema e de Times ",
"admin.customization.restrictCustomEmojiCreationAll": "Permitir que todos possam criar emoji personalizados",
@@ -529,7 +532,7 @@
"admin.metrics.listenAddressDesc": "O endereço que o servidor irá escutar para expor as métricas de performance.",
"admin.metrics.listenAddressEx": "Ex.: \":8067\"",
"admin.metrics.listenAddressTitle": "Endereço à escutar:",
- "admin.mfa.bannerDesc": "<a href='https://docs.mattermost.com/deployment/auth.html' target='_blank'>Multi-factor authentication</a> is available for accounts with AD/LDAP or email login. If other login methods are used, MFA should be configured with the authentication provider.",
+ "admin.mfa.bannerDesc": "<a href='https://docs.mattermost.com/deployment/auth.html' target='_blank'>Autenticação por Multi-fator</a> está disponível para contas com AD/LDAP ou por login por email. Se outro método de login é utilizado, o MFA deve ser configurado com o provedor de autenticação.",
"admin.mfa.cluster": "Alta",
"admin.mfa.title": "Autenticação Multi-Fator",
"admin.nav.help": "Ajuda",
@@ -689,7 +692,7 @@
"admin.service.developerDesc": "Quando verdadeiro, os erros de Javascript serão mostrados em uma barra vermelha no topo da interface de usuário. Não recomendado para uso em produção. ",
"admin.service.developerTitle": "Ativar o Modo Desenvolvedor: ",
"admin.service.enforcMfaTitle": "Obrigar Autenticação Multi-Fator:",
- "admin.service.enforceMfaDesc": "When true, <a href='https://docs.mattermost.com/deployment/auth.html' target='_blank'>multi-factor authentication</a> is required for login. New users will be required to configure MFA on signup. Logged in users without MFA configured are redirected to the MFA setup page until configuration is complete.<br/><br/>If your system has users with login methods other than AD/LDAP and email, MFA must be enforced with the authentication provider outside of Mattermost.",
+ "admin.service.enforceMfaDesc": "Quando verdadeiro, <a href='https://docs.mattermost.com/deployment/auth.html' target='_blank'>autenticação pode multi-fator</a> será requerida para o login. O configuração do MFA será requerida para os novos usuários na inscrição. Usuários logados sem o MFA configurado serão redirecionados para a página de configuração do MFA até a configuração estiver completa.<br/><br/>Se o seu sistema tiver usuários com outros métodos de login que não AD/LDAP e por email, o MFA deverá ser aplicado um provedor de autenticação externo ao Mattermost.",
"admin.service.forward80To443": "Redirecionamento porta 80 para 443:",
"admin.service.forward80To443Description": "Redirecionar todo trafego inseguro da porta 80 para porta segura 443",
"admin.service.googleDescription": "Defina esta chave para permitir a exibição de títulos para pré-visualizações de vídeo do YouTube embutidos. Sem a chave, pré-visualizações do YouTube ainda serão criadas com base em hiperlinks que aparecem nas mensagens ou comentários, mas eles não vão mostrar o título do vídeo. Veja o <a href=\"https://www.youtube.com/watch?v=Im69kzhpR3I\" target='_blank'>Google Developers Tutorial</a> para instruções sobre como obter uma chave.",
@@ -706,7 +709,7 @@
"admin.service.listenAddress": "Endereço à Escutar:",
"admin.service.listenDescription": "O endereço e a porta à qual se ligar e ouvir. Especificando \":8065\" irá ligar-se a todas as interfaces de rede. Especificando \"127.0.0.1:8065\" só irá ligar à interface de rede com esse endereço IP. Se você escolher uma porta de um nível mais baixo (chamadas de \"portas do sistema\" ou \"portas conhecidas\", na faixa de 0-1023), você deve ter permissões para se ligar a essa porta. No Linux, você pode usar: \"sudo setcap cap_net_bind_service=+ep ./bin/platform\" para permitir o Mattermost vincular a portas conhecidas.",
"admin.service.listenExample": "Ex.: \":8065\"",
- "admin.service.mfaDesc": "When true, users with AD/LDAP or email login can add multi-factor authentication to their account using Google Authenticator.",
+ "admin.service.mfaDesc": "Quando verdadeiro, usuários com AD/LDAP ou login por email poderão adicionar a autenticação multi-fator nas suas contas usando o Google Authenticator.",
"admin.service.mfaTitle": "Ativar Autenticação Multi-Fator:",
"admin.service.mobileSessionDays": "Tamanho da sessão para app móvel (dias):",
"admin.service.mobileSessionDaysDesc": "O número de dias desde a última vez que um usuário entrou suas credenciais para expirar a sessão do usuário. Depois de alterar essa configuração, a nova duração da sessão terá efeito após a próxima vez que o usuário digitar suas credenciais.",
@@ -764,6 +767,7 @@
"admin.sidebar.ldap": "AD/LDAP",
"admin.sidebar.legalAndSupport": "Legal e Suporte",
"admin.sidebar.license": "Edição e Licença",
+ "admin.sidebar.linkPreviews": "Visualizações de Links",
"admin.sidebar.localization": "Regionalização",
"admin.sidebar.logging": "Logs",
"admin.sidebar.login": "Login",
@@ -935,8 +939,6 @@
"analytics.system.activeUsers": "Usuários Ativos Com Posts",
"analytics.system.channelTypes": "Tipos de Canal",
"analytics.system.dailyActiveUsers": "Usuários Diários Ativos",
- "analytics.system.expiredBanner": "A licença Enterprise expirou em {date}. Você tem 15 dias a partir desta data para renovar a licença, por favor contate <a href='mailto:commercial@mattermost.com'>commercial@mattermost.com</a>.",
- "analytics.system.expiringBanner": "A licença Enterprise termina em {date}. Para renovar sua licença, por favor contate <a href='mailto:commercial@mattermost.com'>commercial@mattermost.com</a>.",
"analytics.system.monthlyActiveUsers": "Usuários Mensais Ativos",
"analytics.system.postTypes": "Posts, Arquivos e Hashtags",
"analytics.system.privateGroups": "Grupos Privados",
@@ -1140,7 +1142,7 @@
"channel_notifications.never": "Nunca",
"channel_notifications.onlyMentions": "Somente para menções",
"channel_notifications.override": "Selecionar uma opção diferente do \"Padrão\" vai substituir as configurações de notificação global. Notificações na área de trabalho estão disponíveis no Firefox, Safari e Chrome.",
- "channel_notifications.overridePush": "Selecting an option other than \"Global default\" will override the global notification settings for mobile push notifications in account settings. Push notifications must be enabled by the System Admin.",
+ "channel_notifications.overridePush": "Selecionando uma opção diferente de \"Global default\" está irá sobrescrever a configurção global de notificação para notificações de push para mobile na configuração de conta. Notificação por push deve ser habilitada pelo administrador do sistema.",
"channel_notifications.preferences": "Preferências de Notificação para ",
"channel_notifications.sendDesktop": "Enviar notificações de desktop",
"channel_notifications.unreadInfo": "O nome do canal fica em negrito na barra lateral quando houver mensagens não lidas. Selecionando \"Apenas menções\" o canal vai ficar em negrito apenas quando você for mencionado.",
@@ -1287,9 +1289,9 @@
"error.not_found.title": "Página não encontrada",
"error.not_supported.message": "Navegação privada não é suportado",
"error.not_supported.title": "Navegador não suportado",
- "error_bar.expired": "A licença Enterprise expirou; você tem 15 dias a partir da expiração para renovar a licença, por favor contate commercial@mattermost.com para detalhes",
- "error_bar.expiring": "A licença Enterprise termina em {date}. Para renovar sua licença, por favor contate commercial@mattermost.com",
- "error_bar.past_grace": "A licença Enterprise está expirada, por favor contate seu Administrador de Sistema para detalhes",
+ "error_bar.expired": "Licença Enterprise está expirada e alguns recursos podem estar desativados. <a href='{link}' target='_blank'>Por favor, renovar.</a>",
+ "error_bar.expiring": "Licença Enterprise expirou em {date}. <a href='{link}' target='_blank'>Por favor, renovar.</a>",
+ "error_bar.past_grace": "Licença Enterprise está expirada e alguns recursos podem estar desativados. Por favor entre em contato com o Administrador do Sistema para detalhes.",
"error_bar.preview_mode": "Modo de visualização: Notificações por E-mail não foram configuradas",
"file_attachment.download": "Download",
"file_info_preview.size": "Tamanho ",
@@ -1448,7 +1450,7 @@
"help.messaging.write": "**Escreva mensagens** usando a caixa de texto na parte inferior do Mattermost. Pressione ENTER para enviar a mensagem. Use SHIFT+ENTER para criar uma nova linha sem enviar a mensagem.",
"installed_command.header": "Comandos Slash",
"installed_commands.add": "Adicionar Comando Slash",
- "installed_commands.delete.confirm": "This action permanently deletes the slash command and breaks any integrations using it. Are you sure you want to delete it?",
+ "installed_commands.delete.confirm": "Esta ação irá apagar permanentemente o comando slash e irá quebrar qualquer integração que a use. Você está certo que deseja apagar?",
"installed_commands.empty": "Nenhum comando encotrado",
"installed_commands.header": "Comandos Slash",
"installed_commands.help": "Criar comandos slash para uso em integrações internas. Por favor veja {link} para aprender mais.",
@@ -1456,7 +1458,7 @@
"installed_commands.search": "Pesquisar Comandos Slash",
"installed_commands.unnamed_command": "Comando Slash sem Nome",
"installed_incoming_webhooks.add": "Adicionar Webhooks Entrada",
- "installed_incoming_webhooks.delete.confirm": "This action permanently deletes the incoming webhook and breaks any integrations using it. Are you sure you want to delete it?",
+ "installed_incoming_webhooks.delete.confirm": "Esta ação irá apagar permanentemente o webhook de entrada e irá quebrar qualquer integração que a use. Você está certo que deseja apagar?",
"installed_incoming_webhooks.empty": "Nenhum webhook de entrada encontrado",
"installed_incoming_webhooks.header": "Webhooks Entrada",
"installed_incoming_webhooks.help": "Criar URLs para webhook de entrada para uso em integrações externas. Por favor veja {link} para aprender mais.",
@@ -1482,7 +1484,7 @@
"installed_oauth_apps.add": "Adicionar Aplicativo OAuth 2.0",
"installed_oauth_apps.callbackUrls": "URLs Callback (Uma Por Linha)",
"installed_oauth_apps.cancel": "Cancelar",
- "installed_oauth_apps.delete.confirm": "This action permanently deletes the OAuth 2.0 application and breaks any integrations using it. Are you sure you want to delete it?",
+ "installed_oauth_apps.delete.confirm": "Esta ação irá apagar permanentemente o OAuth 2.0 e irá quebrar qualquer integração que a use. Você está certo que deseja apagar?",
"installed_oauth_apps.description": "Descrição",
"installed_oauth_apps.empty": "Nenhum Aplicativo OAuth 2.0 encontrado",
"installed_oauth_apps.header": "Aplicativos OAuth 2.0",
@@ -1498,7 +1500,7 @@
"installed_oauth_apps.trusted.no": "Não",
"installed_oauth_apps.trusted.yes": "Sim",
"installed_outgoing_webhooks.add": "Adicionar Webhooks Saída",
- "installed_outgoing_webhooks.delete.confirm": "This action permanently deletes the outgoing webhook and breaks any integrations using it. Are you sure you want to delete it?",
+ "installed_outgoing_webhooks.delete.confirm": "Esta ação irá apagar permanentemente o webhook de saída e irá quebrar qualquer integração que a use. Você está certo que deseja apagar?",
"installed_outgoing_webhooks.empty": "Nenhum webhook de saída encontrado",
"installed_outgoing_webhooks.header": "Webhooks Saída",
"installed_outgoing_webhooks.help": "Criar URLs para webhook de saída para uso em integrações externas. Por favor veja {link} para aprender mais.",
@@ -1639,17 +1641,17 @@
"more_channels.title": "Mais Canais",
"more_direct_channels.close": "Fechar",
"more_direct_channels.message": "Mensagem",
- "more_direct_channels.new_convo_note": "This will start a new conversation. If you’re adding a lot of people, consider creating a private group instead.",
- "more_direct_channels.new_convo_note.full": "You’ve reached the maximum number of people for this conversation. Consider creating a private group instead.",
+ "more_direct_channels.new_convo_note": "Isto irá iniciar uma nova conversa. Se você adicionar muitas pessoas, considere em criar um grupo privado.",
+ "more_direct_channels.new_convo_note.full": "Você atingiu o número máximo de pessoas nesta conversa. Considere em criar um grupo privado.",
"more_direct_channels.title": "Mensagens Diretas",
"msg_typing.areTyping": "{users} e {last} estão digitando...",
"msg_typing.isTyping": "{user} está digitando...",
"msg_typing.someone": "Alguém",
"multiselect.go": "Ir",
- "multiselect.instructions": "Use up/down arrows to navigate and enter to select",
- "multiselect.numPeopleRemaining": "You can add {num, number} more {num, plural, =0 {people} one {person} other {people}}. ",
- "multiselect.numRemaining": "You can add {num, number} more",
- "multiselect.placeholder": "Search and add members",
+ "multiselect.instructions": "Utilize as setas para cima/baixo para navegar e a tecla enter para selecionar",
+ "multiselect.numPeopleRemaining": "Você pode adicionar {num, number} {num, plural, =0 {pessoas} uma {pessoa} ou {pessoas}} mais. ",
+ "multiselect.numRemaining": "Você pode adicionar mais {num, number}",
+ "multiselect.placeholder": "Procura e adiciona membros",
"navbar.addMembers": "Adicionar Membros",
"navbar.click": "Clique aqui",
"navbar.delete": "Deletar Canal...",
@@ -1704,7 +1706,7 @@
"permalink.error.access": "O permalink pertence a uma mensagem deletada ou a um canal o qual você não tem acesso.",
"post_attachment.collapse": "Mostrar menos...",
"post_attachment.more": "Mostrar mais...",
- "post_body.commentedOn": "Comentado da mensagem de {name}: ",
+ "post_body.commentedOn": "Comentário da mensagem de {name}: ",
"post_body.deleted": "(mensagem deletada)",
"post_body.plusMore": " mais {count} outros arquivos",
"post_body.plusOne": " mais 1 outro arquivo",
diff --git a/webapp/i18n/ru.json b/webapp/i18n/ru.json
index a3ad7388f..954adc8ba 100644
--- a/webapp/i18n/ru.json
+++ b/webapp/i18n/ru.json
@@ -217,8 +217,11 @@
"admin.customization.customEmoji": "Пользовательские смайлы",
"admin.customization.enableCustomEmojiDesc": "Разрешите пользователя создавать Специальные Эмодзи для использования в сообщениях. После разрешения, настройки Специальных Эмодзи могут быть доступны в разделе Команда, нажатием на три точки над боковой панелью и выбором \"Специальные Эмодзи\".",
"admin.customization.enableCustomEmojiTitle": "Включить пользовательские смайлы:",
+ "admin.customization.enableLinkPreviewsDesc": "Enable users to display a preview of website content below the message, if available. When true, website previews can be enabled from Account Settings > Advanced > Preview pre-release features.",
+ "admin.customization.enableLinkPreviewsTitle": "Enable Link Previews:",
"admin.customization.iosAppDownloadLinkDesc": "Добавляет ссылку для скачивания приложения для IOS. Пользователям, которые посещают сайт через мобильный браузер, на специальной странице будет предложена возможность скачать приложение. Оставьте это поле пустым, чтобы предотвратить появление этой страницы.",
"admin.customization.iosAppDownloadLinkTitle": "Ссылка на страницу загрузки приложения для iOS:",
+ "admin.customization.linkPreviews": "Предварительный просмотр ссылок",
"admin.customization.nativeAppLinks": "Ссылки на приложения Mattermost",
"admin.customization.restrictCustomEmojiCreationAdmin": "Разрешите администраторам системы и команд создавать собственные смайлики",
"admin.customization.restrictCustomEmojiCreationAll": "Разрешить каждому создавать пользовательские смайлы",
@@ -764,6 +767,7 @@
"admin.sidebar.ldap": "AD/LDAP",
"admin.sidebar.legalAndSupport": "Право и поддержка",
"admin.sidebar.license": "Редакция и Лицензия",
+ "admin.sidebar.linkPreviews": "Предварительный просмотр ссылок",
"admin.sidebar.localization": "Локализация",
"admin.sidebar.logging": "Журналирование",
"admin.sidebar.login": "Login",
@@ -935,8 +939,6 @@
"analytics.system.activeUsers": "Активные пользователи с сообщениями",
"analytics.system.channelTypes": "Типы канала",
"analytics.system.dailyActiveUsers": "Активность пользователей за день",
- "analytics.system.expiredBanner": "Лицензия Enterprise истекает {date}. Свяжитесь с <a href='mailto:commercial@mattermost.com'>commercial@mattermost.com</a> и обновите лицензию в течение 15 дней.",
- "analytics.system.expiringBanner": "Лицензия Enterprise истекает {date}. Для обновления лицензии свяжитесь с <a href='mailto:commercial@mattermost.com'>commercial@mattermost.com</a>.",
"analytics.system.monthlyActiveUsers": "Активность пользователей за месяц",
"analytics.system.postTypes": "Сообщения, файлы и хештэги",
"analytics.system.privateGroups": "Приватные Группы",
@@ -1287,9 +1289,9 @@
"error.not_found.title": "Страница не найдена",
"error.not_supported.message": "Приватный просмотр не поддерживается",
"error.not_supported.title": "Браузер не поддерживается",
- "error_bar.expired": "Корпоративная лицензия истекла; у вас есть 15 дней, чтобы обновить лицензию. Свяжитесь с commercial@mattermost.com для получения деталей",
- "error_bar.expiring": "Корпоративная лицензия истекает {date}. Чтобы продлить вашу лицензию, свяжитесь с commercial@mattermost.com",
- "error_bar.past_grace": "Корпоративная лицензия истекла, пожалуйста, обратитесь к администратору системы для получения деталей",
+ "error_bar.expired": "Enterprise license is expired and some features may be disabled. <a href='{link}' target='_blank'>Please renew.</a>",
+ "error_bar.expiring": "Enterprise license expires on {date}. <a href='{link}' target='_blank'>Please renew.</a>",
+ "error_bar.past_grace": "Enterprise license is expired and some features may be disabled. Please contact your System Administrator for details.",
"error_bar.preview_mode": "Режим просмотра: Email уведомления не настроены",
"file_attachment.download": "Скачать",
"file_info_preview.size": "Размер ",
diff --git a/webapp/i18n/zh_CN.json b/webapp/i18n/zh-CN.json
index ad35efe10..9212c9e7c 100644
--- a/webapp/i18n/zh_CN.json
+++ b/webapp/i18n/zh-CN.json
@@ -217,8 +217,11 @@
"admin.customization.customEmoji": "自定义表情",
"admin.customization.enableCustomEmojiDesc": "允许用户创建在消息中使用的自定义表情符。启用后,自定义的表情符的设置方式为:切换到一个团队,在侧边栏单击频道上面的三个点,然后选择“自定义表情符”。",
"admin.customization.enableCustomEmojiTitle": "启用自定义表情:",
+ "admin.customization.enableLinkPreviewsDesc": "允许用户在消息下方显示网站预览。当设为是时,网站预览可在帐号设定 > 高级 > 预览先行发布功能开启。",
+ "admin.customization.enableLinkPreviewsTitle": "启用链接预览:",
"admin.customization.iosAppDownloadLinkDesc": "添加iOS应用下载链接。用移动设备访问的用户将看到应用下载提示页面。此栏留空将不显示。",
"admin.customization.iosAppDownloadLinkTitle": "iOS应用下载网址:",
+ "admin.customization.linkPreviews": "链接预览",
"admin.customization.nativeAppLinks": "Mattermost 应用链接",
"admin.customization.restrictCustomEmojiCreationAdmin": "允许系统和团队管理员创建表情符号",
"admin.customization.restrictCustomEmojiCreationAll": "允许每个人可以创建自定义表情",
@@ -764,6 +767,7 @@
"admin.sidebar.ldap": "AD/LDAP",
"admin.sidebar.legalAndSupport": "法律和支持",
"admin.sidebar.license": "版本和许可证",
+ "admin.sidebar.linkPreviews": "链接预览",
"admin.sidebar.localization": "本地化",
"admin.sidebar.logging": "日志",
"admin.sidebar.login": "登录",
@@ -935,8 +939,6 @@
"analytics.system.activeUsers": "有发信息的的正常用户",
"analytics.system.channelTypes": "频道类型",
"analytics.system.dailyActiveUsers": "每日活动用户",
- "analytics.system.expiredBanner": "企业授权已在 {date} 过期。您在即日起有15天时间更新授权,请联系 <a href='mailto:commercial@mattermost.com'>commercial@mattermost.com</a>。",
- "analytics.system.expiringBanner": "企业授权已在 {date} 过期。请更新授权,详情请联系 <a href='mailto:commercial@mattermost.com'>commercial@mattermost.com</a>。",
"analytics.system.monthlyActiveUsers": "每月活动用户",
"analytics.system.postTypes": "发文,文件和标签",
"analytics.system.privateGroups": "私有组",
@@ -1287,9 +1289,9 @@
"error.not_found.title": "页面未找到",
"error.not_supported.message": "私隐浏览不支持",
"error.not_supported.title": "不支持的浏览器",
- "error_bar.expired": "企业授权已过期;您在即日起有15天时间更新授权,详情请联系 commercial@mattermost.com",
- "error_bar.expiring": "企业授权将在 {date} 过期。需要更新授权,详情请联系 commercial@mattermost.com",
- "error_bar.past_grace": "企业授权已过期,详情请联系您的系统管理员",
+ "error_bar.expired": "企业版授权已过期,一些功能已停用。<a href='{link}' target='_blank'>请更新授权。</a>",
+ "error_bar.expiring": "企业版授权将于 {date} 过期。<a href='{link}' target='_blank'>请更新授权。</a>",
+ "error_bar.past_grace": "企业版授权已过期,一些功能已停用。请联系您的系统管理员了解详情。",
"error_bar.preview_mode": "预览模式: 未配置邮件通知",
"file_attachment.download": "下载",
"file_info_preview.size": "大小",
diff --git a/webapp/i18n/zh_TW.json b/webapp/i18n/zh-TW.json
index 320af58c5..d9c0cadae 100644
--- a/webapp/i18n/zh_TW.json
+++ b/webapp/i18n/zh-TW.json
@@ -217,8 +217,11 @@
"admin.customization.customEmoji": "自訂繪文字",
"admin.customization.enableCustomEmojiDesc": "允許使用者新增用於訊息當中的自訂繪文字。允許之後,自訂繪文字設定的檢視方式為:變更到一個團隊,按頻道側邊欄上面的三個點,然後選擇\"自訂繪文字\"。",
"admin.customization.enableCustomEmojiTitle": "啟用自訂繪文字:",
+ "admin.customization.enableLinkPreviewsDesc": "允許使用者在可能時訊息下方顯示網站預覽。啟用時,網頁預覽可以在帳號設定 > 進階 > 預覽預先發佈功能開啟",
+ "admin.customization.enableLinkPreviewsTitle": "啟用連結預覽:",
"admin.customization.iosAppDownloadLinkDesc": "新增下載 iOS 應用程式的連結。用行動網頁瀏覽器存取站台的使用者將會看到提示頁面以下載應用程式。此欄留空則不會出現提示頁面。",
"admin.customization.iosAppDownloadLinkTitle": "iOS 應用程式下載連結:",
+ "admin.customization.linkPreviews": "連結預覽",
"admin.customization.nativeAppLinks": "Mattermost 應用程式連結",
"admin.customization.restrictCustomEmojiCreationAdmin": "允許系統及團隊管理員新增自訂繪文字",
"admin.customization.restrictCustomEmojiCreationAll": "允許所有人新增自訂繪文字",
@@ -764,6 +767,7 @@
"admin.sidebar.ldap": "AD/LDAP",
"admin.sidebar.legalAndSupport": "法律與支援",
"admin.sidebar.license": "版本與授權",
+ "admin.sidebar.linkPreviews": "連結預覽",
"admin.sidebar.localization": "語言",
"admin.sidebar.logging": "記錄",
"admin.sidebar.login": "登入",
@@ -935,8 +939,6 @@
"analytics.system.activeUsers": "有發文的活躍使用者",
"analytics.system.channelTypes": "頻道類型",
"analytics.system.dailyActiveUsers": "每日活躍使用者",
- "analytics.system.expiredBanner": "企業版授權將在{date}過期。請在該日起15天內更新授權。詳情請洽<a href='mailto:commercial@mattermost.com'>commercial@mattermost.com</a>。",
- "analytics.system.expiringBanner": "企業版授權將在{date}過期。請洽<a href='mailto:commercial@mattermost.com'>commercial@mattermost.com</a>以更新授權。",
"analytics.system.monthlyActiveUsers": "每月活躍使用者",
"analytics.system.postTypes": "發文,檔案與#標籤",
"analytics.system.privateGroups": "私人群組",
@@ -1287,9 +1289,9 @@
"error.not_found.title": "找不到頁面",
"error.not_supported.message": "不支援隱私瀏覽",
"error.not_supported.title": "不支援此瀏覽器",
- "error_bar.expired": "企業版授權已過期。請在過期日起15天內更新授權。詳情請洽 commercial@mattermost.com",
- "error_bar.expiring": "企業版授權將在 {date} 過期。請聯繫 commercial@mattermost.com 更新授權。",
- "error_bar.past_grace": "企業版授權已過期,詳情請洽系統管理員。",
+ "error_bar.expired": "企業版授權已過期,某些功能已被關閉。<a href='{link}' target='_blank'>請由此更新。</a>",
+ "error_bar.expiring": "企業版授權將於{date}過期。<a href='{link}' target='_blank'>請由此更新。</a>",
+ "error_bar.past_grace": "企業版授權已過期,某些功能已被關閉。詳請聯絡系統管理員。",
"error_bar.preview_mode": "預覽模式:電子郵件通知尚未設定",
"file_attachment.download": "下載",
"file_info_preview.size": "大小 ",
diff --git a/webapp/sass/components/_modal.scss b/webapp/sass/components/_modal.scss
index 3698e8dc9..bfc082ad3 100644
--- a/webapp/sass/components/_modal.scss
+++ b/webapp/sass/components/_modal.scss
@@ -566,7 +566,7 @@
.more-modal__actions {
flex-grow: 0;
flex-shrink: 0;
- margin: 5px 0 10px;
+ margin: 5px 0;
padding-left: 20px;
}
diff --git a/webapp/sass/components/_multi-select.scss b/webapp/sass/components/_multi-select.scss
index a33116aa4..beceb7b9c 100644
--- a/webapp/sass/components/_multi-select.scss
+++ b/webapp/sass/components/_multi-select.scss
@@ -29,7 +29,6 @@
.Select-value-label {
overflow: hidden;
- text-overflow: ellipsis;
}
}
diff --git a/webapp/sass/layout/_markdown.scss b/webapp/sass/layout/_markdown.scss
index e6ab35f8a..1f8ea041e 100644
--- a/webapp/sass/layout/_markdown.scss
+++ b/webapp/sass/layout/_markdown.scss
@@ -51,6 +51,7 @@
.hljs {
position: relative;
+ visibility: visible;
}
}
@@ -163,11 +164,11 @@ code {
}
.hljs {
+ background: #f8f8f8;
+ color: #333;
display: block;
overflow-x: auto;
padding: 0.5em;
- color: #333;
- background: #f8f8f8;
}
.container {
@@ -175,7 +176,7 @@ code {
}
.links {
- margin-top: 30px;
font-size: 1.2em;
+ margin-top: 30px;
}
} \ No newline at end of file
diff --git a/webapp/sass/layout/_post.scss b/webapp/sass/layout/_post.scss
index 8d14bfafc..1e1dd4b08 100644
--- a/webapp/sass/layout/_post.scss
+++ b/webapp/sass/layout/_post.scss
@@ -3,7 +3,7 @@
.custom-textarea {
background: transparent;
border: 1px solid #cccccc;
- height: auto;
+ height: 100%;
line-height: 20px;
min-height: 36px;
overflow-x: hidden;
@@ -360,7 +360,10 @@
.post-create__container {
label {
- font-weight: normal;
+ font-weight: normal;
+ }
+ .custom-textarea {
+ overflow: hidden;
}
form {
@@ -380,6 +383,8 @@
}
.custom-textarea {
+ -ms-overflow-style: auto;
+ overflow: auto;
padding-right: 43px;
}
}
@@ -581,6 +586,12 @@
}
}
+ &.post--system {
+ .status {
+ visibility: hidden;
+ }
+ }
+
.post__img {
padding-top: 0;
}
@@ -588,6 +599,7 @@
.status-wrapper {
cursor: auto;
height: 14px;
+ pointer-events: none;
.status {
bottom: auto;
diff --git a/webapp/sass/responsive/_mobile.scss b/webapp/sass/responsive/_mobile.scss
index 66c288a48..4fbec082a 100644
--- a/webapp/sass/responsive/_mobile.scss
+++ b/webapp/sass/responsive/_mobile.scss
@@ -13,6 +13,7 @@
.Select-value-label {
max-width: 190px;
+ text-overflow: ellipsis;
}
}
@@ -555,6 +556,13 @@
}
.modal {
+ .modal--scroll {
+ .modal-body {
+ max-height: calc(100vh - 62px);
+ overflow: auto;
+ }
+ }
+
.nav-pills {
> li {
&.active {
@@ -1628,6 +1636,7 @@
}
}
}
+
.attachment {
.attachment__image {
&.attachment__image--openraph {
@@ -1641,6 +1650,7 @@
left: 0;
position: fixed;
top: 0;
+ z-index: 9999;
.tutorial__content {
.tutorial__steps {
diff --git a/webapp/sass/routes/_signup.scss b/webapp/sass/routes/_signup.scss
index c73c32656..13ee95e76 100644
--- a/webapp/sass/routes/_signup.scss
+++ b/webapp/sass/routes/_signup.scss
@@ -450,6 +450,7 @@
.signup-team-dir {
background: #fafafa;
border-top: 1px solid #d5d5d5;
+ overflow: hidden;
&:first-child {
border: none;
@@ -458,7 +459,7 @@
.icon {
cursor: pointer;
float: left;
- margin: 18px 7px 0 15px;
+ margin: 16px 7px 0 15px;
opacity: .45;
svg {
diff --git a/webapp/stores/channel_store.jsx b/webapp/stores/channel_store.jsx
index f303b0190..41fa76b39 100644
--- a/webapp/stores/channel_store.jsx
+++ b/webapp/stores/channel_store.jsx
@@ -10,7 +10,7 @@ import UserStore from 'stores/user_store.jsx';
var ChannelUtils;
var Utils;
import {ActionTypes, Constants} from 'utils/constants.jsx';
-import {isSystemMessage} from 'utils/post_utils.jsx';
+import {isSystemMessage, isFromWebhook} from 'utils/post_utils.jsx';
const NotificationPrefs = Constants.NotificationPrefs;
const CHANGE_EVENT = 'change';
@@ -521,7 +521,7 @@ ChannelStore.dispatchToken = AppDispatcher.register((payload) => {
return;
}
- if (action.post.user_id === UserStore.getCurrentId() && !isSystemMessage(action.post)) {
+ if (action.post.user_id === UserStore.getCurrentId() && !isSystemMessage(action.post) && !isFromWebhook(action.post)) {
return;
}
diff --git a/webapp/stores/notification_store.jsx b/webapp/stores/notification_store.jsx
index f32e71047..f32107ef7 100644
--- a/webapp/stores/notification_store.jsx
+++ b/webapp/stores/notification_store.jsx
@@ -82,6 +82,10 @@ class NotificationStoreClass extends EventEmitter {
title = channel.display_name;
}
+ if (title === '') {
+ title = msgProps.channel_display_name;
+ }
+
let notifyText = post.message.replace(/\n+/g, ' ');
if (notifyText.length > 50) {
notifyText = notifyText.substring(0, 49) + '...';
diff --git a/webapp/utils/async_client.jsx b/webapp/utils/async_client.jsx
index 2ecb0f07d..1fc19b5f2 100644
--- a/webapp/utils/async_client.jsx
+++ b/webapp/utils/async_client.jsx
@@ -64,26 +64,31 @@ export function checkVersion() {
}
export function getChannels() {
- if (isCallInProgress('getChannels')) {
- return null;
- }
+ return new Promise((resolve, reject) => {
+ if (isCallInProgress('getChannels')) {
+ resolve();
+ return;
+ }
- callTracker.getChannels = utils.getTimestamp();
+ callTracker.getChannels = utils.getTimestamp();
- return Client.getChannels(
- (data) => {
- callTracker.getChannels = 0;
+ Client.getChannels(
+ (data) => {
+ callTracker.getChannels = 0;
- AppDispatcher.handleServerAction({
- type: ActionTypes.RECEIVED_CHANNELS,
- channels: data
- });
- },
- (err) => {
- callTracker.getChannels = 0;
- dispatchError(err, 'getChannels');
- }
- );
+ AppDispatcher.handleServerAction({
+ type: ActionTypes.RECEIVED_CHANNELS,
+ channels: data
+ });
+ resolve();
+ },
+ (err) => {
+ callTracker.getChannels = 0;
+ dispatchError(err, 'getChannels');
+ reject();
+ }
+ );
+ });
}
export function getChannel(id) {
@@ -130,7 +135,7 @@ export function getMyChannelMembers() {
resolve();
},
(err) => {
- callTracker.getChannelsUnread = 0;
+ callTracker.getMyChannelMembers = 0;
dispatchError(err, 'getMyChannelMembers');
reject(new Error('Unable to getMyChannelMembers'));
}
diff --git a/webapp/utils/constants.jsx b/webapp/utils/constants.jsx
index 3a16992ca..d8fc169a3 100644
--- a/webapp/utils/constants.jsx
+++ b/webapp/utils/constants.jsx
@@ -443,7 +443,7 @@ export const Constants = {
linkColor: '#2f81b7',
buttonBg: '#1dacfc',
buttonColor: '#FFFFFF',
- mentionHighlightBg: '#fff2bb',
+ mentionHighlightBg: '#f3e197',
mentionHighlightLink: '#2f81b7',
codeTheme: 'github',
image: defaultThemeImage
@@ -468,7 +468,7 @@ export const Constants = {
linkColor: '#2389d7',
buttonBg: '#23A2FF',
buttonColor: '#FFFFFF',
- mentionHighlightBg: '#fff2bb',
+ mentionHighlightBg: '#f3e197',
mentionHighlightLink: '#2f81b7',
codeTheme: 'github',
image: mattermostThemeImage
diff --git a/webapp/utils/post_utils.jsx b/webapp/utils/post_utils.jsx
index 0b908c55b..1f2021e4a 100644
--- a/webapp/utils/post_utils.jsx
+++ b/webapp/utils/post_utils.jsx
@@ -12,6 +12,10 @@ export function isSystemMessage(post) {
return post.type && (post.type.lastIndexOf(Constants.SYSTEM_MESSAGE_PREFIX) === 0);
}
+export function isFromWebhook(post) {
+ return post.props && post.props.from_webhook === 'true';
+}
+
export function isPostOwner(post) {
return UserStore.getCurrentId() === post.user_id;
}
diff --git a/webapp/utils/utils.jsx b/webapp/utils/utils.jsx
index b4afc65b3..b3370e88c 100644
--- a/webapp/utils/utils.jsx
+++ b/webapp/utils/utils.jsx
@@ -538,14 +538,14 @@ export function applyTheme(theme) {
if (theme.mentionBj) {
changeCss('.sidebar--left .nav-pills__unread-indicator, .app__body .new-messages__button div', 'background:' + theme.mentionBj);
- changeCss('.sidebar--left .badge', 'background:' + theme.mentionBj + '!important;');
- changeCss('.multi-teams .team-sidebar .team-wrapper .team-container .team-btn .badge', 'background:' + theme.mentionBj + '!important;');
+ changeCss('.sidebar--left .badge', 'background:' + theme.mentionBj);
+ changeCss('.multi-teams .team-sidebar .team-wrapper .team-container .team-btn .badge', 'background:' + theme.mentionBj);
}
if (theme.mentionColor) {
- changeCss('.sidebar--left .nav-pills__unread-indicator, .app__body .new-messages__button div', 'color:' + theme.mentionColor);
- changeCss('.sidebar--left .badge', 'color:' + theme.mentionColor + '!important;');
- changeCss('.multi-teams .team-sidebar .team-wrapper .team-container .team-btn .badge', 'color:' + theme.mentionColor + '!important;');
+ changeCss('.app__body .sidebar--left .nav-pills__unread-indicator, .app__body .new-messages__button div', 'color:' + theme.mentionColor);
+ changeCss('.app__body .sidebar--left .badge', 'color:' + theme.mentionColor);
+ changeCss('.app__body .multi-teams .team-sidebar .team-wrapper .team-container .team-btn .badge', 'color:' + theme.mentionColor);
}
if (theme.centerChannelBg) {
@@ -623,7 +623,7 @@ export function applyTheme(theme) {
changeCss('@media(min-width: 768px){.app__body .post:hover, .app__body .more-modal__list .more-modal__row:hover, .app__body .modal .settings-modal .settings-table .settings-content .section-min:hover', 'background:' + changeOpacity(theme.centerChannelColor, 0.08));
changeCss('.app__body .more-modal__row.more-modal__row--selected, .app__body .date-separator.hovered--before:after, .app__body .date-separator.hovered--after:before, .app__body .new-separator.hovered--after:before, .app__body .new-separator.hovered--before:after', 'background:' + changeOpacity(theme.centerChannelColor, 0.07));
changeCss('@media(min-width: 768px){.app__body .suggestion-list__content .command:hover, .app__body .mentions__name:hover, .app__body .dropdown-menu>li>a:focus, .app__body .dropdown-menu>li>a:hover', 'background:' + changeOpacity(theme.centerChannelColor, 0.15));
- changeCss('.app__body .suggestion--selected, .app__body .bot-indicator', 'background:' + changeOpacity(theme.centerChannelColor, 0.15), 1);
+ changeCss('.app__body .suggestion--selected, .app__body .emoticon-suggestion:hover, .app__body .bot-indicator', 'background:' + changeOpacity(theme.centerChannelColor, 0.15), 1);
changeCss('code, .app__body .form-control[disabled], .app__body .form-control[readonly], .app__body fieldset[disabled] .form-control', 'background:' + changeOpacity(theme.centerChannelColor, 0.1));
changeCss('@media(min-width: 960px){.app__body .post.current--user:hover .post__body ', 'background: none;');
changeCss('.app__body .sidebar--right', 'color:' + theme.centerChannelColor);
@@ -670,7 +670,7 @@ export function applyTheme(theme) {
if (theme.mentionHighlightBg) {
changeCss('.app__body .mention--highlight, .app__body .search-highlight', 'background:' + theme.mentionHighlightBg);
- changeCss('.mention-comment', 'border-color:' + theme.mentionHighlightBg + ' !important');
+ changeCss('.app__body .post.post--comment .post__body.mention-comment', 'border-color:' + theme.mentionHighlightBg);
changeCss('.app__body .post.post--highlight', 'background:' + changeOpacity(theme.mentionHighlightBg, 0.5));
}