summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md3
-rw-r--r--api/admin.go2
-rw-r--r--api/templates/email_change_body.html2
-rw-r--r--api/user.go6
-rw-r--r--web/react/components/channel_loader.jsx14
-rw-r--r--web/react/components/posts_view.jsx10
-rw-r--r--web/react/components/search_results.jsx15
-rw-r--r--web/react/components/user_settings/manage_command_hooks.jsx4
-rw-r--r--web/react/stores/post_store.jsx17
-rw-r--r--web/react/stores/socket_store.jsx14
-rw-r--r--web/react/utils/async_client.jsx13
11 files changed, 61 insertions, 39 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c27041165..bd9772b2b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -144,6 +144,9 @@ The following is for informational purposes only, no action needed. Mattermost a
##### Licenses Table
1. Added `Licenses` Table
+##### Commands Table
+1. Added `Commands` Table
+
#### Known Issues
- Navigating to a page with new messages containing inline images added via markdown causes the channel to scroll up and down while loading the inline images.
diff --git a/api/admin.go b/api/admin.go
index e8cb8b3c7..5a645dc97 100644
--- a/api/admin.go
+++ b/api/admin.go
@@ -120,6 +120,8 @@ func getConfig(c *Context, w http.ResponseWriter, r *http.Request) {
cfg := model.ConfigFromJson(strings.NewReader(json))
json = cfg.ToJson()
+ w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
+ w.Header().Set("Expires", "0")
w.Write([]byte(json))
}
diff --git a/api/templates/email_change_body.html b/api/templates/email_change_body.html
index 4f28584c4..41b1bcd7d 100644
--- a/api/templates/email_change_body.html
+++ b/api/templates/email_change_body.html
@@ -18,7 +18,7 @@
<tr>
<td style="border-bottom: 1px solid #ddd; padding: 0 0 20px;">
<h2 style="font-weight: normal; margin-top: 10px;">{{.Props.Title}}</h2>
- <p>{{.Props.Info}}</p>
+ <p>{{.Html.Info}}</p>
</td>
</tr>
<tr>
diff --git a/api/user.go b/api/user.go
index 8f381aeda..db8de5f6a 100644
--- a/api/user.go
+++ b/api/user.go
@@ -1761,14 +1761,14 @@ func sendEmailChangeEmailAndForget(c *Context, oldEmail, newEmail, teamDisplayNa
go func() {
subjectPage := NewServerTemplatePage("email_change_subject", c.Locale)
- subjectPage.Props["Subject"] = c.T("api.templates.email_change_body",
+ subjectPage.Props["Subject"] = c.T("api.templates.email_change_subject",
map[string]interface{}{"TeamDisplayName": teamDisplayName})
bodyPage := NewServerTemplatePage("email_change_body", c.Locale)
bodyPage.Props["SiteURL"] = siteURL
bodyPage.Props["Title"] = c.T("api.templates.email_change_body.title")
- bodyPage.Props["Info"] = c.T("api.templates.email_change_body.info",
- map[string]interface{}{"TeamDisplayName": teamDisplayName, "NewEmail": newEmail})
+ bodyPage.Html["Info"] = template.HTML(c.T("api.templates.email_change_body.info",
+ map[string]interface{}{"TeamDisplayName": teamDisplayName, "NewEmail": newEmail}))
if err := utils.SendMail(oldEmail, subjectPage.Render(), bodyPage.Render()); err != nil {
l4g.Error(utils.T("api.user.send_email_change_email_and_forget.error"), err)
diff --git a/web/react/components/channel_loader.jsx b/web/react/components/channel_loader.jsx
index 174c8c4e1..2aa28d5c4 100644
--- a/web/react/components/channel_loader.jsx
+++ b/web/react/components/channel_loader.jsx
@@ -20,31 +20,31 @@ import {intlShape, injectIntl, defineMessages} from 'mm-intl';
const holders = defineMessages({
socketError: {
id: 'channel_loader.socketError',
- defaultMessage: 'Please check connection, Mattermost unreachable. If issue persists, ask administrator to check WebSocket port.'
+ defaultMessage: SocketStore.getDefaultTranslations().socketError
},
someone: {
id: 'channel_loader.someone',
- defaultMessage: 'Someone'
+ defaultMessage: SocketStore.getDefaultTranslations().someone
},
posted: {
id: 'channel_loader.posted',
- defaultMessage: 'Posted'
+ defaultMessage: SocketStore.getDefaultTranslations().posted
},
uploadedImage: {
id: 'channel_loader.uploadedImage',
- defaultMessage: ' uploaded an image'
+ defaultMessage: SocketStore.getDefaultTranslations().uploadedImage
},
uploadedFile: {
id: 'channel_loader.uploadedFile',
- defaultMessage: ' uploaded a file'
+ defaultMessage: SocketStore.getDefaultTranslations().uploadedFile
},
something: {
id: 'channel_loader.something',
- defaultMessage: ' did something new'
+ defaultMessage: SocketStore.getDefaultTranslations().something
},
wrote: {
id: 'channel_loader.wrote',
- defaultMessage: ' wrote: '
+ defaultMessage: SocketStore.getDefaultTranslations().wrote
}
});
diff --git a/web/react/components/posts_view.jsx b/web/react/components/posts_view.jsx
index ebe19abad..19ab7d5aa 100644
--- a/web/react/components/posts_view.jsx
+++ b/web/react/components/posts_view.jsx
@@ -535,7 +535,15 @@ function FloatingTimestamp({isScrolling, post}) {
return <noscript />;
}
- const dateString = Utils.getDateForUnixTicks(post.create_at).toDateString();
+ const dateString = (
+ <FormattedDate
+ value={post.create_at}
+ weekday='short'
+ day='2-digit'
+ month='short'
+ year='numeric'
+ />
+ );
let className = 'post-list__timestamp';
if (isScrolling) {
diff --git a/web/react/components/search_results.jsx b/web/react/components/search_results.jsx
index 4adc3afe0..12c066734 100644
--- a/web/react/components/search_results.jsx
+++ b/web/react/components/search_results.jsx
@@ -15,13 +15,16 @@ function getStateFromStores() {
const results = SearchStore.getSearchResults();
const channels = new Map();
- const channelIds = results.order.map((postId) => results.posts[postId].channel_id);
- for (const id of channelIds) {
- if (channels.has(id)) {
- continue;
- }
- channels.set(id, ChannelStore.get(id));
+ if (results && results.order) {
+ const channelIds = results.order.map((postId) => results.posts[postId].channel_id);
+ for (const id of channelIds) {
+ if (channels.has(id)) {
+ continue;
+ }
+
+ channels.set(id, ChannelStore.get(id));
+ }
}
return {
diff --git a/web/react/components/user_settings/manage_command_hooks.jsx b/web/react/components/user_settings/manage_command_hooks.jsx
index f4009aeaa..bd0659a47 100644
--- a/web/react/components/user_settings/manage_command_hooks.jsx
+++ b/web/react/components/user_settings/manage_command_hooks.jsx
@@ -257,7 +257,7 @@ export default class ManageCommandCmds extends React.Component {
let triggerDiv;
if (cmd.trigger && cmd.trigger.length !== 0) {
triggerDiv = (
- <div className='padding-top'>
+ <div className='padding-top x2'>
<strong>
<FormattedMessage
id='user.settings.cmds.trigger'
@@ -371,7 +371,7 @@ export default class ManageCommandCmds extends React.Component {
/>
</a>
<a
- className='webcmd__remove'
+ className='webhook__remove webcmd__remove'
href='#'
onClick={this.removeCmd.bind(this, cmd.id)}
>
diff --git a/web/react/stores/post_store.jsx b/web/react/stores/post_store.jsx
index b5bb93576..f5c342163 100644
--- a/web/react/stores/post_store.jsx
+++ b/web/react/stores/post_store.jsx
@@ -83,8 +83,6 @@ class PostStoreClass extends EventEmitter {
this.getCommentDraft = this.getCommentDraft.bind(this);
this.clearDraftUploads = this.clearDraftUploads.bind(this);
this.clearCommentDraftUploads = this.clearCommentDraftUploads.bind(this);
- this.storeLatestUpdate = this.storeLatestUpdate.bind(this);
- this.getLatestUpdate = this.getLatestUpdate.bind(this);
this.getCurrentUsersLatestPost = this.getCurrentUsersLatestPost.bind(this);
this.getCommentCount = this.getCommentCount.bind(this);
@@ -258,7 +256,7 @@ class PostStoreClass extends EventEmitter {
const np = newPosts.posts[pid];
if (np.delete_at === 0) {
combinedPosts.posts[pid] = np;
- if (combinedPosts.order.indexOf(pid) === -1) {
+ if (combinedPosts.order.indexOf(pid) === -1 && newPosts.order.indexOf(pid) !== -1) {
combinedPosts.order.push(pid);
}
}
@@ -507,19 +505,6 @@ class PostStoreClass extends EventEmitter {
}
});
}
- storeLatestUpdate(channelId, time) {
- if (!this.postsInfo.hasOwnProperty(channelId)) {
- this.postsInfo[channelId] = {};
- }
- this.postsInfo[channelId].latestPost = time;
- }
- getLatestUpdate(channelId) {
- if (this.postsInfo.hasOwnProperty(channelId) && this.postsInfo[channelId].hasOwnProperty('latestPost')) {
- return this.postsInfo[channelId].latestPost;
- }
-
- return 0;
- }
getCommentCount(post) {
const posts = this.getAllPosts(post.channel_id).posts;
diff --git a/web/react/stores/socket_store.jsx b/web/react/stores/socket_store.jsx
index e1b65fe14..424c7fe57 100644
--- a/web/react/stores/socket_store.jsx
+++ b/web/react/stores/socket_store.jsx
@@ -32,6 +32,8 @@ class SocketStoreClass extends EventEmitter {
this.failCount = 0;
+ this.translations = this.getDefaultTranslations();
+
this.initialize();
}
@@ -174,6 +176,18 @@ class SocketStoreClass extends EventEmitter {
this.translations = messages;
}
+ getDefaultTranslations() {
+ return ({
+ socketError: 'Please check connection, Mattermost unreachable. If issue persists, ask administrator to check WebSocket port.',
+ someone: 'Someone',
+ posted: 'Posted',
+ uploadedImage: ' uploaded an image',
+ uploadedFile: ' uploaded a file',
+ something: ' did something new',
+ wrote: ' wrote: '
+ });
+ }
+
close() {
if (conn && conn.readyState === WebSocket.OPEN) {
conn.close();
diff --git a/web/react/utils/async_client.jsx b/web/react/utils/async_client.jsx
index c8676f45d..45cdf699f 100644
--- a/web/react/utils/async_client.jsx
+++ b/web/react/utils/async_client.jsx
@@ -521,18 +521,25 @@ export function getPosts(id) {
return;
}
- if (PostStore.getAllPosts(channelId) == null) {
+ const postList = PostStore.getAllPosts(channelId);
+
+ if ($.isEmptyObject(postList) || postList.order.length < Constants.POST_CHUNK_SIZE) {
getPostsPage(channelId, Constants.POST_CHUNK_SIZE);
return;
}
- const latestUpdate = PostStore.getLatestUpdate(channelId);
+ const latestPost = PostStore.getLatestPost(channelId);
+ let latestPostTime = 0;
+
+ if (latestPost != null && latestPost.update_at != null) {
+ latestPostTime = latestPost.create_at;
+ }
callTracker['getPosts_' + channelId] = utils.getTimestamp();
client.getPosts(
channelId,
- latestUpdate,
+ latestPostTime,
(data, textStatus, xhr) => {
if (xhr.status === 304 || !data) {
return;