DEV: Plugin-api methods for user-notifications route customizations (#24873)
This commit is contained in:
parent
f7aefffea7
commit
c051bfc2fc
|
@ -523,6 +523,7 @@ GEM
|
|||
PLATFORMS
|
||||
aarch64-linux
|
||||
arm64-darwin-20
|
||||
arm64-darwin-21
|
||||
arm64-darwin-22
|
||||
x86_64-darwin-18
|
||||
x86_64-darwin-19
|
||||
|
|
|
@ -11,6 +11,11 @@ import { iconHTML } from "discourse-common/lib/icon-library";
|
|||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import I18n from "discourse-i18n";
|
||||
|
||||
const _beforeLoadMoreCallbacks = [];
|
||||
export function addBeforeLoadMoreCallback(fn) {
|
||||
_beforeLoadMoreCallbacks.push(fn);
|
||||
}
|
||||
|
||||
export default class UserNotificationsController extends Controller {
|
||||
@service modal;
|
||||
@service appEvents;
|
||||
|
@ -102,6 +107,14 @@ export default class UserNotificationsController extends Controller {
|
|||
|
||||
@action
|
||||
loadMore() {
|
||||
if (
|
||||
_beforeLoadMoreCallbacks.length &&
|
||||
!_beforeLoadMoreCallbacks.some((fn) => fn(this))
|
||||
) {
|
||||
// Return early if any callbacks return false, short-circuiting the default loading more logic
|
||||
return;
|
||||
}
|
||||
|
||||
this.model.loadMore();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import { addUserMenuProfileTabItem } from "discourse/components/user-menu/profil
|
|||
import { addDiscoveryQueryParam } from "discourse/controllers/discovery/list";
|
||||
import { registerFullPageSearchType } from "discourse/controllers/full-page-search";
|
||||
import { registerCustomPostMessageCallback as registerCustomPostMessageCallback1 } from "discourse/controllers/topic";
|
||||
import { addBeforeLoadMoreCallback as addBeforeLoadMoreNotificationsCallback } from "discourse/controllers/user-notifications";
|
||||
import { registerCustomUserNavMessagesDropdownRow } from "discourse/controllers/user-private-messages";
|
||||
import {
|
||||
addExtraIconRenderer,
|
||||
|
@ -88,6 +89,7 @@ import {
|
|||
addSaveableUserOptionField,
|
||||
} from "discourse/models/user";
|
||||
import { setNewCategoryDefaultColors } from "discourse/routes/new-category";
|
||||
import { setNotificationsLimit } from "discourse/routes/user-notifications";
|
||||
import { addComposerSaveErrorCallback } from "discourse/services/composer";
|
||||
import {
|
||||
addToHeaderIcons,
|
||||
|
@ -141,7 +143,7 @@ import { modifySelectKit } from "select-kit/mixins/plugin-api";
|
|||
// docs/CHANGELOG-JAVASCRIPT-PLUGIN-API.md whenever you change the version
|
||||
// using the format described at https://keepachangelog.com/en/1.0.0/.
|
||||
|
||||
export const PLUGIN_API_VERSION = "1.18.0";
|
||||
export const PLUGIN_API_VERSION = "1.19.0";
|
||||
|
||||
// This helper prevents us from applying the same `modifyClass` over and over in test mode.
|
||||
function canModify(klass, type, resolverName, changes) {
|
||||
|
@ -819,6 +821,21 @@ class PluginApi {
|
|||
registerCustomPostMessageCallback1(type, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a callback that will be evaluated when infinite scrolling would cause
|
||||
* more notifications to be loaded. This can be used to prevent loading more unless
|
||||
* a specific condition is met.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* api.addBeforeLoadMoreNotificationsCallback((controller) => {
|
||||
* return controller.allowLoadMore;
|
||||
* });
|
||||
*/
|
||||
addBeforeLoadMoreNotificationsCallback(fn) {
|
||||
addBeforeLoadMoreNotificationsCallback(fn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes a setting associated with a widget. For example, if
|
||||
* you wanted small avatars in the post stream:
|
||||
|
@ -1773,6 +1790,18 @@ class PluginApi {
|
|||
setNewCategoryDefaultColors(backgroundColor, textColor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the number of notifications that are loaded at /my/notifications
|
||||
*
|
||||
* ```
|
||||
* api.setNotificationsLimit(20)
|
||||
* ```
|
||||
*
|
||||
**/
|
||||
setNotificationsLimit(limit) {
|
||||
setNotificationsLimit(limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a callback to modify search results before displaying them.
|
||||
*
|
||||
|
|
|
@ -2,6 +2,13 @@ import ViewingActionType from "discourse/mixins/viewing-action-type";
|
|||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
import I18n from "discourse-i18n";
|
||||
|
||||
const DEFAULT_LIMIT = 60;
|
||||
let limit = DEFAULT_LIMIT;
|
||||
|
||||
export function setNotificationsLimit(newLimit) {
|
||||
limit = newLimit;
|
||||
}
|
||||
|
||||
export default DiscourseRoute.extend(ViewingActionType, {
|
||||
controllerName: "user-notifications",
|
||||
queryParams: { filter: { refreshModel: true } },
|
||||
|
@ -16,6 +23,7 @@ export default DiscourseRoute.extend(ViewingActionType, {
|
|||
return this.store.find("notification", {
|
||||
username,
|
||||
filter: params.filter,
|
||||
limit,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
|
@ -27,6 +27,10 @@
|
|||
<UserMenu::MenuItem @item={{item}} />
|
||||
{{/each}}
|
||||
<ConditionalLoadingSpinner @condition={{this.loading}} />
|
||||
<PluginOutlet
|
||||
@name="user-notifications-list-bottom"
|
||||
@outletArgs={{hash controller=this}}
|
||||
/>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
|
@ -7,6 +7,14 @@ 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.19.0] - 2023-12-13
|
||||
|
||||
### Added
|
||||
|
||||
- Added `setNotificationsLimit` function, which sets a new limit for how many notifications are loaded for the user notifications route
|
||||
|
||||
- Added `addBeforeLoadMoreNotificationsCallback` function, which takes a function as the argument. All added callbacks are evaluated before `loadMore` is triggered for user notifications. If any callback returns false, notifications will not be loaded.
|
||||
|
||||
## [1.18.0] - 2023-12-1
|
||||
|
||||
### Added
|
||||
|
|
|
@ -52,6 +52,10 @@ module PageObjects
|
|||
self
|
||||
end
|
||||
|
||||
def click_primary_navigation_item(name)
|
||||
page.find(primary_navigation_selector(name)).click
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def primary_navigation_selector(name)
|
||||
|
|
|
@ -27,6 +27,10 @@ module PageObjects
|
|||
def has_no_notification?(notification)
|
||||
page.has_no_css?(".notification a[href='#{notification.url}']")
|
||||
end
|
||||
|
||||
def has_notification_count_of?(count)
|
||||
page.has_css?(".notification", count: count)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
describe "User notifications", type: :system do
|
||||
fab!(:user)
|
||||
let(:user_notifications_page) { PageObjects::Pages::UserNotifications.new }
|
||||
let(:user_page) { PageObjects::Pages::User.new }
|
||||
|
||||
fab!(:read_notification) { Fabricate(:notification, user: user, read: true) }
|
||||
fab!(:unread_notification) { Fabricate(:notification, user: user, read: false) }
|
||||
|
@ -10,7 +11,7 @@ describe "User notifications", type: :system do
|
|||
before { sign_in(user) }
|
||||
|
||||
describe "filtering" do
|
||||
it "saves custom picture and system assigned pictures" do
|
||||
it "correctly filters all / read / unread notifications" do
|
||||
user_notifications_page.visit(user)
|
||||
user_notifications_page.filter_dropdown
|
||||
expect(user_notifications_page).to have_selected_filter_value("all")
|
||||
|
@ -28,4 +29,26 @@ describe "User notifications", type: :system do
|
|||
expect(user_notifications_page).to have_notification(unread_notification)
|
||||
end
|
||||
end
|
||||
|
||||
describe "setNotificationLimit & addBeforeLoadMoreNotificationsCallback plugin-api functions" do
|
||||
it "Allows blocking loading via callback and limit" do
|
||||
user_page.visit(user)
|
||||
|
||||
page.execute_script <<~JS
|
||||
require("discourse/lib/plugin-api").withPluginApi("1.19.0", (api) => {
|
||||
api.setNotificationsLimit(1);
|
||||
|
||||
api.addBeforeLoadMoreNotificationsCallback(() => {
|
||||
return false;
|
||||
})
|
||||
})
|
||||
JS
|
||||
|
||||
user_page.click_primary_navigation_item("notifications")
|
||||
|
||||
# It is 1 here because we blocked infinite scrolling. Even though the limit is 1,
|
||||
# without the callback, we would have 2 items here as it immediately fires another request.
|
||||
expect(user_notifications_page).to have_notification_count_of(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue