diff --git a/app/assets/javascripts/discourse/app/initializers/edit-notification-clicks-tracker.js b/app/assets/javascripts/discourse/app/initializers/edit-notification-clicks-tracker.js
new file mode 100644
index 00000000000..c9e29142ac7
--- /dev/null
+++ b/app/assets/javascripts/discourse/app/initializers/edit-notification-clicks-tracker.js
@@ -0,0 +1,16 @@
+import { setLastEditNotificationClick } from "discourse/models/post-stream";
+
+export default {
+ name: "edit-notification-clicks-tracker",
+
+ initialize(container) {
+ container
+ .lookup("service:app-events")
+ .on(
+ "edit-notification:clicked",
+ ({ topicId, postNumber, revisionNumber }) => {
+ setLastEditNotificationClick(topicId, postNumber, revisionNumber);
+ }
+ );
+ },
+};
diff --git a/app/assets/javascripts/discourse/app/models/post-stream.js b/app/assets/javascripts/discourse/app/models/post-stream.js
index 2c0777538d8..a28a4833212 100644
--- a/app/assets/javascripts/discourse/app/models/post-stream.js
+++ b/app/assets/javascripts/discourse/app/models/post-stream.js
@@ -15,6 +15,23 @@ import { isEmpty } from "@ember/utils";
import { loadTopicView } from "discourse/models/topic";
import { schedule } from "@ember/runloop";
+let _lastEditNotificationClick = null;
+export function setLastEditNotificationClick(
+ topicId,
+ postNumber,
+ revisionNumber
+) {
+ _lastEditNotificationClick = {
+ topicId,
+ postNumber,
+ revisionNumber,
+ };
+}
+
+export function resetLastEditNotificationClick() {
+ _lastEditNotificationClick = null;
+}
+
export default RestModel.extend({
_identityMap: null,
posts: null,
@@ -324,7 +341,7 @@ export default RestModel.extend({
} else {
const postWeWant = this.posts.findBy("post_number", opts.nearPost);
if (postWeWant) {
- return Promise.resolve();
+ return Promise.resolve().then(() => this._checkIfShouldShowRevisions());
}
}
@@ -345,6 +362,7 @@ export default RestModel.extend({
timelineLookup: json.timeline_lookup,
loaded: true,
});
+ this._checkIfShouldShowRevisions();
})
.catch((result) => {
this.errorLoading(result);
@@ -1207,4 +1225,24 @@ export default RestModel.extend({
topic.set("noRetry", result.jqXHR.status === 403);
}
},
+
+ _checkIfShouldShowRevisions() {
+ if (_lastEditNotificationClick) {
+ const copy = _lastEditNotificationClick;
+ resetLastEditNotificationClick();
+ const postsNumbers = this.posts.mapBy("post_number");
+ if (
+ copy.topicId === this.topic.id &&
+ postsNumbers.includes(copy.postNumber)
+ ) {
+ schedule("afterRender", () => {
+ this.appEvents.trigger(
+ "post:show-revision",
+ copy.postNumber,
+ copy.revisionNumber
+ );
+ });
+ }
+ }
+ },
});
diff --git a/app/assets/javascripts/discourse/app/widgets/default-notification-item.js b/app/assets/javascripts/discourse/app/widgets/default-notification-item.js
index 8a183f4e87e..ff9d09f2975 100644
--- a/app/assets/javascripts/discourse/app/widgets/default-notification-item.js
+++ b/app/assets/javascripts/discourse/app/widgets/default-notification-item.js
@@ -29,6 +29,12 @@ export const DefaultNotificationItem = createWidget(
if (attrs.is_warning) {
classNames.push("is-warning");
}
+ const notificationType = attrs.notification_type;
+ const lookup = this.site.get("notificationLookup");
+ const notificationName = lookup[notificationType];
+ if (notificationName) {
+ classNames.push(notificationName.replaceAll("_", "-"));
+ }
return classNames;
},
@@ -156,19 +162,14 @@ export const DefaultNotificationItem = createWidget(
e.preventDefault();
this.sendWidgetEvent("linkClicked");
- DiscourseURL.routeTo(this.url(this.attrs.data), {
- afterRouteComplete: () => {
- if (!this.attrs.data.revision_number) {
- return;
- }
-
- this.appEvents.trigger(
- "post:show-revision",
- this.attrs.post_number,
- this.attrs.data.revision_number
- );
- },
- });
+ if (this.attrs.data.revision_number) {
+ this.appEvents.trigger("edit-notification:clicked", {
+ topicId: this.attrs.topic_id,
+ postNumber: this.attrs.post_number,
+ revisionNumber: this.attrs.data.revision_number,
+ });
+ }
+ DiscourseURL.routeTo(this.url(this.attrs.data));
},
mouseUp(event) {
diff --git a/app/assets/javascripts/discourse/tests/acceptance/edit-notification-click-test.js b/app/assets/javascripts/discourse/tests/acceptance/edit-notification-click-test.js
new file mode 100644
index 00000000000..00f5fa61c1b
--- /dev/null
+++ b/app/assets/javascripts/discourse/tests/acceptance/edit-notification-click-test.js
@@ -0,0 +1,57 @@
+import { acceptance, queryAll } from "discourse/tests/helpers/qunit-helpers";
+import { click, visit } from "@ember/test-helpers";
+import { test } from "qunit";
+
+acceptance("Edit Notification Click", function (needs) {
+ needs.user();
+ needs.pretender((server, helper) => {
+ server.get("/posts/133/revisions/1.json", () => {
+ return helper.response({
+ created_at: "2021-07-30T11:19:59.549Z",
+ post_id: 133,
+ previous_hidden: false,
+ current_hidden: false,
+ first_revision: 2,
+ previous_revision: null,
+ current_revision: 2,
+ next_revision: null,
+ last_revision: 2,
+ current_version: 2,
+ version_count: 2,
+ username: "velesin",
+ display_username: "velesin",
+ avatar_template: "/letter_avatar_proxy/v4/letter/j/13edae/{size}.png",
+ edit_reason: null,
+ body_changes: {
+ inline:
+ '
Hello world this is a test
another edit!
',
+ side_by_side:
+ 'Hello world this is a test
Hello world this is a test
This is an edit!
',
+ side_by_side_markdown:
+ 'Hello world this is a test | Hello world this is a test\n\nThis is an edit! |
',
+ },
+ title_changes: null,
+ user_changes: null,
+ wiki: false,
+ can_edit: true,
+ });
+ });
+ });
+
+ test("history modal is shown when navigating from a non-topic page", async function (assert) {
+ await visit("/");
+ await click(".d-header-icons #current-user");
+ await click("#quick-access-notifications .edited");
+ const [v1, v2] = queryAll(".history-modal .revision-content");
+ assert.equal(
+ v1.textContent.trim(),
+ "Hello world this is a test",
+ "history modal for the edited post is shown"
+ );
+ assert.equal(
+ v2.textContent.trim(),
+ "Hello world this is a testThis is an edit!",
+ "history modal for the edited post is shown"
+ );
+ });
+});
diff --git a/app/assets/javascripts/discourse/tests/acceptance/notifications-test.js b/app/assets/javascripts/discourse/tests/acceptance/notifications-test.js
index 674f5327e92..42946e0786e 100644
--- a/app/assets/javascripts/discourse/tests/acceptance/notifications-test.js
+++ b/app/assets/javascripts/discourse/tests/acceptance/notifications-test.js
@@ -35,7 +35,7 @@ acceptance("User Notifications", function (needs) {
await visit("/"); // wait for re-render
- assert.equal(count("#quick-access-notifications li"), 5);
+ assert.equal(count("#quick-access-notifications li"), 6);
// high priority, unread notification - should be first
diff --git a/app/assets/javascripts/discourse/tests/acceptance/user-test.js b/app/assets/javascripts/discourse/tests/acceptance/user-test.js
index 6c8c2acfcbc..3bec0ce6d4c 100644
--- a/app/assets/javascripts/discourse/tests/acceptance/user-test.js
+++ b/app/assets/javascripts/discourse/tests/acceptance/user-test.js
@@ -45,7 +45,7 @@ acceptance("User Routes", function (needs) {
const $links = queryAll(".item.notification a");
assert.ok(
- $links[1].href.includes(
+ $links[2].href.includes(
"/u/eviltrout/notifications/likes-received?acting_username=aquaman"
)
);
diff --git a/app/assets/javascripts/discourse/tests/fixtures/notification-fixtures.js b/app/assets/javascripts/discourse/tests/fixtures/notification-fixtures.js
index ac2fe07fe97..0dbc392ab2e 100644
--- a/app/assets/javascripts/discourse/tests/fixtures/notification-fixtures.js
+++ b/app/assets/javascripts/discourse/tests/fixtures/notification-fixtures.js
@@ -4,6 +4,15 @@ import { NOTIFICATION_TYPES } from "./concerns/notification-types";
export default {
"/notifications": {
notifications: [
+ {
+ id: 5340,
+ notification_type: NOTIFICATION_TYPES.edited,
+ read: false,
+ post_number: 1,
+ topic_id: 130,
+ slug: "lorem-ipsum-dolor-sit-amet",
+ data: { topic_title: "edited topic 443", display_username: "velesin", revision_number: 1, original_post_id: 133, original_post_type: 1, original_username: "velesin" },
+ },
{
id: 123,
notification_type: NOTIFICATION_TYPES.replied,
diff --git a/app/assets/javascripts/discourse/tests/helpers/qunit-helpers.js b/app/assets/javascripts/discourse/tests/helpers/qunit-helpers.js
index 2d5a3fbf5ff..b92c4dd61bb 100644
--- a/app/assets/javascripts/discourse/tests/helpers/qunit-helpers.js
+++ b/app/assets/javascripts/discourse/tests/helpers/qunit-helpers.js
@@ -46,6 +46,7 @@ import {
cleanUpComposerUploadMarkdownResolver,
cleanUpComposerUploadProcessor,
} from "discourse/components/composer-editor";
+import { resetLastEditNotificationClick } from "discourse/models/post-stream";
const LEGACY_ENV = !setupApplicationTest;
@@ -282,6 +283,7 @@ export function acceptance(name, optionsOrCallback) {
cleanUpComposerUploadHandler();
cleanUpComposerUploadProcessor();
cleanUpComposerUploadMarkdownResolver();
+ resetLastEditNotificationClick();
app._runInitializer("instanceInitializers", (initName, initializer) => {
if (initializer && initializer.teardown) {
initializer.teardown(this.container);
diff --git a/app/assets/javascripts/discourse/tests/integration/widgets/user-menu-test.js b/app/assets/javascripts/discourse/tests/integration/widgets/user-menu-test.js
index 624c6837197..f41fd83fc34 100644
--- a/app/assets/javascripts/discourse/tests/integration/widgets/user-menu-test.js
+++ b/app/assets/javascripts/discourse/tests/integration/widgets/user-menu-test.js
@@ -37,25 +37,25 @@ discourseModule(
async test(assert) {
const $links = queryAll(".quick-access-panel li a");
- assert.equal($links.length, 5);
- assert.ok($links[0].href.includes("/t/a-slug/123"));
+ assert.equal($links.length, 6);
+ assert.ok($links[1].href.includes("/t/a-slug/123"));
assert.ok(
- $links[1].href.includes(
+ $links[2].href.includes(
"/u/eviltrout/notifications/likes-received?acting_username=aquaman"
)
);
assert.equal(
- $links[1].text,
+ $links[2].text,
`aquaman ${I18n.t("notifications.liked_consolidated_description", {
count: 5,
})}`
);
- assert.ok($links[2].href.includes("/u/test2/messages/group/test"));
+ assert.ok($links[3].href.includes("/u/test2/messages/group/test"));
assert.ok(
- $links[2].innerHTML.includes(
+ $links[3].innerHTML.includes(
I18n.t("notifications.group_message_summary", {
count: 5,
group_name: "test",
@@ -63,16 +63,16 @@ discourseModule(
)
);
- assert.ok($links[3].href.includes("/u/test1"));
+ assert.ok($links[4].href.includes("/u/test1"));
assert.ok(
- $links[3].innerHTML.includes(
+ $links[4].innerHTML.includes(
I18n.t("notifications.invitee_accepted", { username: "test1" })
)
);
- assert.ok($links[4].href.includes("/g/test"));
+ assert.ok($links[5].href.includes("/g/test"));
assert.ok(
- $links[4].innerHTML.includes(
+ $links[5].innerHTML.includes(
I18n.t("notifications.membership_request_accepted", {
group_name: "test",
})