DEV: adds a `addChatDrawerStateCallback` API (#20640)
Usage: ```javascript api.addChatDrawerStateCallback(({ isDrawerActive, isDrawerExpanded }) => { // do something }); ``` Note this commit also uses this new API to add a css class (chat-drawer-active) on the body when the drawer is active.
This commit is contained in:
parent
6bb89ffea8
commit
727100d1e2
|
@ -117,6 +117,14 @@ export default {
|
|||
|
||||
api.addToHeaderIcons("chat-header-icon");
|
||||
|
||||
api.addChatDrawerStateCallback(({ isDrawerActive }) => {
|
||||
if (isDrawerActive) {
|
||||
document.body.classList.add("chat-drawer-active");
|
||||
} else {
|
||||
document.body.classList.remove("chat-drawer-active");
|
||||
}
|
||||
});
|
||||
|
||||
api.decorateChatMessage(function (chatMessage, chatChannel) {
|
||||
if (!this.currentUser) {
|
||||
return;
|
||||
|
|
|
@ -4,6 +4,7 @@ import {
|
|||
resetChatMessageDecorators,
|
||||
} from "discourse/plugins/chat/discourse/components/chat-message";
|
||||
import { registerChatComposerButton } from "discourse/plugins/chat/discourse/lib/chat-composer-buttons";
|
||||
import { addChatDrawerStateCallback } from "discourse/plugins/chat/discourse/services/chat-state-manager";
|
||||
|
||||
/**
|
||||
* Class exposing the javascript API available to plugins and themes.
|
||||
|
@ -19,6 +20,15 @@ import { registerChatComposerButton } from "discourse/plugins/chat/discourse/lib
|
|||
* @param {ChatChannel} chatChannel - model
|
||||
*/
|
||||
|
||||
/**
|
||||
* Callback used to decorate a chat message
|
||||
*
|
||||
* @callback PluginApi~chatDrawerStateCallbak
|
||||
* @param {Object} state
|
||||
* @param {boolean} state.isDrawerActive - is the chat drawer active
|
||||
* @param {boolean} state.isDrawerExpanded - is the chat drawer expanded
|
||||
*/
|
||||
|
||||
/**
|
||||
* Decorate a chat message
|
||||
*
|
||||
|
@ -65,6 +75,22 @@ import { registerChatComposerButton } from "discourse/plugins/chat/discourse/lib
|
|||
* });
|
||||
*/
|
||||
|
||||
/**
|
||||
* Callback when the sate of the chat drawer changes
|
||||
*
|
||||
* @memberof PluginApi
|
||||
* @instance
|
||||
* @function addChatDrawerStateCallback
|
||||
* @param {PluginApi~chatDrawerStateCallbak} callback
|
||||
* @example
|
||||
*
|
||||
* api.addChatDrawerStateCallback(({isDrawerExpanded, isDrawerActive}) => {
|
||||
* if (isDrawerActive && isDrawerExpanded) {
|
||||
* // do something
|
||||
* }
|
||||
* });
|
||||
*/
|
||||
|
||||
export default {
|
||||
name: "chat-plugin-api",
|
||||
after: "inject-discourse-objects",
|
||||
|
@ -88,6 +114,14 @@ export default {
|
|||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (!apiPrototype.hasOwnProperty("addChatDrawerStateCallback")) {
|
||||
Object.defineProperty(apiPrototype, "addChatDrawerStateCallback", {
|
||||
value(callback) {
|
||||
addChatDrawerStateCallback(callback);
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -9,6 +9,15 @@ const PREFERRED_MODE_STORE_NAMESPACE = "discourse_chat_";
|
|||
const FULL_PAGE_CHAT = "FULL_PAGE_CHAT";
|
||||
const DRAWER_CHAT = "DRAWER_CHAT";
|
||||
|
||||
let chatDrawerStateCallbacks = [];
|
||||
|
||||
export function addChatDrawerStateCallback(callback) {
|
||||
chatDrawerStateCallbacks.push(callback);
|
||||
}
|
||||
|
||||
export function resetChatDrawerStateCallbacks() {
|
||||
chatDrawerStateCallbacks = [];
|
||||
}
|
||||
export default class ChatStateManager extends Service {
|
||||
@service chat;
|
||||
@service router;
|
||||
|
@ -51,12 +60,14 @@ export default class ChatStateManager extends Service {
|
|||
}
|
||||
|
||||
this.chat.updatePresence();
|
||||
this.#publishStateChange();
|
||||
}
|
||||
|
||||
didCloseDrawer() {
|
||||
this.set("isDrawerActive", false);
|
||||
this.set("isDrawerExpanded", false);
|
||||
this.chat.updatePresence();
|
||||
this.#publishStateChange();
|
||||
}
|
||||
|
||||
didExpandDrawer() {
|
||||
|
@ -68,11 +79,13 @@ export default class ChatStateManager extends Service {
|
|||
didCollapseDrawer() {
|
||||
this.set("isDrawerActive", true);
|
||||
this.set("isDrawerExpanded", false);
|
||||
this.#publishStateChange();
|
||||
}
|
||||
|
||||
didToggleDrawer() {
|
||||
this.set("isDrawerExpanded", !this.isDrawerExpanded);
|
||||
this.set("isDrawerActive", true);
|
||||
this.#publishStateChange();
|
||||
}
|
||||
|
||||
get isFullPagePreferred() {
|
||||
|
@ -119,4 +132,13 @@ export default class ChatStateManager extends Service {
|
|||
get lastKnownChatURL() {
|
||||
return this._chatURL || "/chat";
|
||||
}
|
||||
|
||||
#publishStateChange() {
|
||||
const state = {
|
||||
isDrawerActive: this.isDrawerActive,
|
||||
isDrawerExpanded: this.isDrawerExpanded,
|
||||
};
|
||||
|
||||
chatDrawerStateCallbacks.forEach((callback) => callback(state));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,20 @@ RSpec.describe "Drawer", type: :system, js: true do
|
|||
end
|
||||
end
|
||||
|
||||
context "when toggling open/close" do
|
||||
it "toggles a css class on body" do
|
||||
visit("/")
|
||||
|
||||
chat_page.open_from_header
|
||||
|
||||
expect(page.find("body.chat-drawer-active")).to be_visible
|
||||
|
||||
drawer.close
|
||||
|
||||
expect(page.find("body:not(.chat-drawer-active)")).to be_visible
|
||||
end
|
||||
end
|
||||
|
||||
context "when going from drawer to full page" do
|
||||
fab!(:channel_1) { Fabricate(:chat_channel) }
|
||||
fab!(:channel_2) { Fabricate(:chat_channel) }
|
||||
|
|
|
@ -2,6 +2,11 @@ import { module, test } from "qunit";
|
|||
import { setupTest } from "ember-qunit";
|
||||
import Site from "discourse/models/site";
|
||||
import sinon from "sinon";
|
||||
import { getOwner } from "discourse-common/lib/get-owner";
|
||||
import {
|
||||
addChatDrawerStateCallback,
|
||||
resetChatDrawerStateCallbacks,
|
||||
} from "discourse/plugins/chat/discourse/services/chat-state-manager";
|
||||
|
||||
module(
|
||||
"Discourse Chat | Unit | Service | chat-state-manager",
|
||||
|
@ -9,7 +14,7 @@ module(
|
|||
setupTest(hooks);
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
this.subject = this.owner.lookup("service:chat-state-manager");
|
||||
this.subject = getOwner(this).lookup("service:chat-state-manager");
|
||||
});
|
||||
|
||||
hooks.afterEach(function () {
|
||||
|
@ -129,5 +134,24 @@ module(
|
|||
assert.strictEqual(this.subject.lastKnownChatURL, "/foo");
|
||||
sinon.assert.calledTwice(stub);
|
||||
});
|
||||
|
||||
test("callbacks", function (assert) {
|
||||
this.state = null;
|
||||
addChatDrawerStateCallback((state) => {
|
||||
this.state = state;
|
||||
});
|
||||
|
||||
this.subject.didOpenDrawer();
|
||||
|
||||
assert.strictEqual(this.state.isDrawerActive, true);
|
||||
assert.strictEqual(this.state.isDrawerExpanded, true);
|
||||
|
||||
this.subject.didCloseDrawer();
|
||||
|
||||
assert.strictEqual(this.state.isDrawerActive, false);
|
||||
assert.strictEqual(this.state.isDrawerExpanded, false);
|
||||
|
||||
resetChatDrawerStateCallbacks();
|
||||
});
|
||||
}
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue