Skip to content

Commit

Permalink
DEV: Add registerCustomLastUnreadUrlCallbackto plugin API (discours…
Browse files Browse the repository at this point in the history
  • Loading branch information
pmusaraj authored Mar 23, 2022
1 parent 4a39850 commit 99a6f32
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 20 deletions.
18 changes: 17 additions & 1 deletion app/assets/javascripts/discourse/app/lib/plugin-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ import { registerTopicFooterDropdown } from "discourse/lib/register-topic-footer
import { registerDesktopNotificationHandler } from "discourse/lib/desktop-notifications";
import { replaceFormatter } from "discourse/lib/utilities";
import { replaceTagRenderer } from "discourse/lib/render-tag";
import { registerCustomLastUnreadUrlCallback } from "discourse/models/topic";
import { setNewCategoryDefaultColors } from "discourse/routes/new-category";
import { addSearchResultsCallback } from "discourse/lib/search";
import {
Expand All @@ -98,7 +99,7 @@ import { consolePrefix } from "discourse/lib/source-identifier";
// based on Semantic Versioning 2.0.0. Please update the changelog at
// docs/CHANGELOG-JAVASCRIPT-PLUGIN-API.md whenever you change the version
// using the format described at https://keepachangelog.com/en/1.0.0/.
const PLUGIN_API_VERSION = "1.1.0";
const PLUGIN_API_VERSION = "1.2.0";

// This helper prevents us from applying the same `modifyClass` over and over in test mode.
function canModify(klass, type, resolverName, changes) {
Expand Down Expand Up @@ -1290,6 +1291,21 @@ class PluginApi {
replaceTagRenderer(fn);
}

/**
* Register a custom last unread url for a topic list item.
* If a non-null value is returned, it will be used right away.
*
* Example:
*
* function testLastUnreadUrl(context) {
* return context.urlForPostNumber(1);
* }
* api.registerCustomLastUnreadUrlCallback(testLastUnreadUrl);
**/
registerCustomLastUnreadUrlCallback(fn) {
registerCustomLastUnreadUrlCallback(fn);
}

/**
* Registers custom languages for use with HighlightJS.
*
Expand Down
23 changes: 23 additions & 0 deletions app/assets/javascripts/discourse/app/models/topic.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export function loadTopicView(topic, args) {
}

export const ID_CONSTRAINT = /^\d+$/;
let _customLastUnreadUrlCallbacks = [];

const Topic = RestModel.extend({
message: null,
Expand Down Expand Up @@ -256,6 +257,19 @@ const Topic = RestModel.extend({

@discourseComputed("last_read_post_number", "highest_post_number", "url")
lastUnreadUrl(lastReadPostNumber, highestPostNumber) {
let customUrl = null;
_customLastUnreadUrlCallbacks.some((cb) => {
const result = cb(this);
if (result) {
customUrl = result;
return true;
}
});

if (customUrl) {
return customUrl;
}

if (highestPostNumber <= lastReadPostNumber) {
if (this.get("category.navigate_to_first_post_after_read")) {
return this.urlForPostNumber(1);
Expand Down Expand Up @@ -876,4 +890,13 @@ export function mergeTopic(topicId, data) {
);
}

export function registerCustomLastUnreadUrlCallback(fn) {
_customLastUnreadUrlCallbacks.push(fn);
}

// Should only be used in tests
export function clearCustomLastUnreadUrlCallbacks() {
_customLastUnreadUrlCallbacks.clear();
}

export default Topic;
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { acceptance, query } from "discourse/tests/helpers/qunit-helpers";
import { clearCustomLastUnreadUrlCallbacks } from "discourse/models/topic";
import { test } from "qunit";
import { visit } from "@ember/test-helpers";
import { withPluginApi } from "discourse/lib/plugin-api";

acceptance("Topic list plugin API", function () {
function customLastUnreadUrl(context) {
return `${context.urlForPostNumber(1)}?overriden`;
}

test("Overrides lastUnreadUrl", async function (assert) {
try {
withPluginApi("1.2.0", (api) => {
api.registerCustomLastUnreadUrlCallback(customLastUnreadUrl);
});

await visit("/");
assert.strictEqual(
query(
".topic-list .topic-list-item:first-child a.raw-topic-link"
).getAttribute("href"),
"/t/error-after-upgrade-to-0-9-7-9/11557/1?overriden"
);
} finally {
clearCustomLastUnreadUrlCallbacks();
}
});
});
51 changes: 32 additions & 19 deletions docs/CHANGELOG-JAVASCRIPT-PLUGIN-API.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,49 @@

All notable changes to the Discourse JavaScript plugin API located at
app/assets/javascripts/discourse/app/lib/plugin-api.js will be described
in this file..
in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.2.0] - 2022-03-18

### Added

- Adds `registerCustomLastUnreadUrlCallback`, which allows users to register a custom
function that returns a last unread url for a topic list item. When multiple callbacks
are registered, the first non-null value that is returned will be used.

## [1.1.0] - 2021-12-15

### Added

- Adds `addPosterIcons`, which allows users to add multiple icons to a poster. The
addition of this function also makes the existing `addPosterIcon` now an alias to this
function. Users may now just use `addPosterIcons` for both one or many icons. This
function allows users to now return many icons depending on an `attrs`.
addition of this function also makes the existing `addPosterIcon` now an alias to this
function. Users may now just use `addPosterIcons` for both one or many icons. This
function allows users to now return many icons depending on an `attrs`.

## [1.0.0] - 2021-11-25

### Removed

- Removes the `addComposerUploadProcessor` function, which is no longer used in
favour of `addComposerUploadPreProcessor`. The former was used to add preprocessors
for client side uploads via jQuery file uploader (described at
https://github.com/blueimp/jQuery-File-Upload/wiki/Options#file-processing-options).
The new `addComposerUploadPreProcessor` adds preprocessors for client side
uploads in the form of an Uppy plugin. See https://uppy.io/docs/writing-plugins/
for the Uppy documentation, but other examples of preprocessors in core can be found
in the UppyMediaOptimization and UppyChecksum classes. This has been done because
of the overarching move towards Uppy in the Discourse codebase rather than
jQuery fileupload, which will eventually be removed altogether as a broader effort
to remove jQuery from the codebase.
favour of `addComposerUploadPreProcessor`. The former was used to add preprocessors
for client side uploads via jQuery file uploader (described at
https://github.com/blueimp/jQuery-File-Upload/wiki/Options#file-processing-options).
The new `addComposerUploadPreProcessor` adds preprocessors for client side
uploads in the form of an Uppy plugin. See https://uppy.io/docs/writing-plugins/
for the Uppy documentation, but other examples of preprocessors in core can be found
in the UppyMediaOptimization and UppyChecksum classes. This has been done because
of the overarching move towards Uppy in the Discourse codebase rather than
jQuery fileupload, which will eventually be removed altogether as a broader effort
to remove jQuery from the codebase.

### Changed

- Changes `addComposerUploadHandler`'s behaviour. Instead of being only usable
for single files at a time, now multiple files are sent to the upload handler
at once. These multiple files are sent based on the groups in which they are
added (e.g. multiple files selected from the system upload dialog, or multiple
files dropped in to the composer). Files will be sent in buckets to the handlers
they match.
for single files at a time, now multiple files are sent to the upload handler
at once. These multiple files are sent based on the groups in which they are
added (e.g. multiple files selected from the system upload dialog, or multiple
files dropped in to the composer). Files will be sent in buckets to the handlers
they match.

0 comments on commit 99a6f32

Please sign in to comment.