DEV: Move ChatThreadsManager to channel (#20304)
This commit changes the ChatThreadsManager into a native class instead of an ember service, and initializes it for every ChatChannel model. This way each channel has its own thread manager and cache that we can load/unload as needed, and we also move activeThread to the channel since it makes more sense to keep it there, not inside the chat service. The pattern of calling setOwner with the passed in owner from ChatChannel is adapted from the latest ember docs, and is needed to avoid the error below when calling services from the native class: > Attempting to lookup an injected property on an object without a container, ensure that the object was instantiated via a container It works well _only_ if we use our own getOwner wrapper from addon/lib/get-owner, which is for backwards compat. c.f. https://guides.emberjs.com/release/in-depth-topics/native-classes-in-depth/
This commit is contained in:
parent
183946a549
commit
c0a086a988
|
@ -9,7 +9,7 @@ export default class ChatThreadPanel extends Component {
|
||||||
@service router;
|
@service router;
|
||||||
|
|
||||||
get thread() {
|
get thread() {
|
||||||
return this.chat.activeThread;
|
return this.chat.activeChannel.activeThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
get title() {
|
get title() {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import Service, { inject as service } from "@ember/service";
|
import { inject as service } from "@ember/service";
|
||||||
|
import { setOwner } from "@ember/application";
|
||||||
import Promise from "rsvp";
|
import Promise from "rsvp";
|
||||||
import ChatThread from "discourse/plugins/chat/discourse/models/chat-thread";
|
import ChatThread from "discourse/plugins/chat/discourse/models/chat-thread";
|
||||||
import { tracked } from "@glimmer/tracking";
|
import { tracked } from "@glimmer/tracking";
|
||||||
|
@ -6,19 +7,23 @@ import { TrackedObject } from "@ember-compat/tracked-built-ins";
|
||||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The ChatThreadsManager service is responsible for managing the loaded chat threads
|
The ChatThreadsManager is responsible for managing the loaded chat threads
|
||||||
for the current chat channel.
|
for a ChatChannel model.
|
||||||
|
|
||||||
It provides helpers to facilitate using and managing loaded threads instead of constantly
|
It provides helpers to facilitate using and managing loaded threads instead of constantly
|
||||||
fetching them from the server.
|
fetching them from the server.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export default class ChatThreadsManager extends Service {
|
export default class ChatThreadsManager {
|
||||||
@service chatSubscriptionsManager;
|
@service chatSubscriptionsManager;
|
||||||
@service chatApi;
|
@service chatApi;
|
||||||
@service currentUser;
|
@service currentUser;
|
||||||
@tracked _cached = new TrackedObject();
|
@tracked _cached = new TrackedObject();
|
||||||
|
|
||||||
|
constructor(owner) {
|
||||||
|
setOwner(this, owner);
|
||||||
|
}
|
||||||
|
|
||||||
async find(channelId, threadId, options = { fetchIfNotFound: true }) {
|
async find(channelId, threadId, options = { fetchIfNotFound: true }) {
|
||||||
const existingThread = this.#findStale(threadId);
|
const existingThread = this.#findStale(threadId);
|
||||||
if (existingThread) {
|
if (existingThread) {
|
||||||
|
@ -30,11 +35,6 @@ export default class ChatThreadsManager extends Service {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// whenever the active channel changes, do this
|
|
||||||
resetCache() {
|
|
||||||
this._cached = new TrackedObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
get threads() {
|
get threads() {
|
||||||
return Object.values(this._cached);
|
return Object.values(this._cached);
|
||||||
}
|
}
|
|
@ -6,6 +6,8 @@ import { ajax } from "discourse/lib/ajax";
|
||||||
import { escapeExpression } from "discourse/lib/utilities";
|
import { escapeExpression } from "discourse/lib/utilities";
|
||||||
import { tracked } from "@glimmer/tracking";
|
import { tracked } from "@glimmer/tracking";
|
||||||
import slugifyChannel from "discourse/plugins/chat/discourse/lib/slugify-channel";
|
import slugifyChannel from "discourse/plugins/chat/discourse/lib/slugify-channel";
|
||||||
|
import ChatThreadsManager from "discourse/plugins/chat/discourse/lib/chat-threads-manager";
|
||||||
|
import { getOwner } from "discourse-common/lib/get-owner";
|
||||||
|
|
||||||
export const CHATABLE_TYPES = {
|
export const CHATABLE_TYPES = {
|
||||||
directMessageChannel: "DirectMessage",
|
directMessageChannel: "DirectMessage",
|
||||||
|
@ -65,6 +67,9 @@ export default class ChatChannel extends RestModel {
|
||||||
@tracked description;
|
@tracked description;
|
||||||
@tracked chatableType;
|
@tracked chatableType;
|
||||||
@tracked status;
|
@tracked status;
|
||||||
|
@tracked activeThread;
|
||||||
|
|
||||||
|
threadsManager = new ChatThreadsManager(getOwner(this));
|
||||||
|
|
||||||
get escapedTitle() {
|
get escapedTitle() {
|
||||||
return escapeExpression(this.title);
|
return escapeExpression(this.title);
|
||||||
|
|
|
@ -3,19 +3,16 @@ import { inject as service } from "@ember/service";
|
||||||
|
|
||||||
export default class ChatChannelThread extends DiscourseRoute {
|
export default class ChatChannelThread extends DiscourseRoute {
|
||||||
@service router;
|
@service router;
|
||||||
@service chatThreadsManager;
|
|
||||||
@service chatStateManager;
|
@service chatStateManager;
|
||||||
@service chat;
|
@service chat;
|
||||||
|
|
||||||
async model(params) {
|
async model(params) {
|
||||||
return this.chatThreadsManager.find(
|
const channel = this.modelFor("chat.channel");
|
||||||
this.modelFor("chat.channel").id,
|
return channel.threadsManager.find(channel.id, params.threadId);
|
||||||
params.threadId
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
afterModel(model) {
|
afterModel(model) {
|
||||||
this.chat.activeThread = model;
|
this.chat.activeChannel.activeThread = model;
|
||||||
this.chatStateManager.openSidePanel();
|
this.chatStateManager.openSidePanel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,12 @@ import { action } from "@ember/object";
|
||||||
|
|
||||||
@withChatChannel
|
@withChatChannel
|
||||||
export default class ChatChannelRoute extends DiscourseRoute {
|
export default class ChatChannelRoute extends DiscourseRoute {
|
||||||
@service chatThreadsManager;
|
@service chat;
|
||||||
@service chatStateManager;
|
@service chatStateManager;
|
||||||
|
|
||||||
@action
|
@action
|
||||||
willTransition(transition) {
|
willTransition(transition) {
|
||||||
this.chat.activeThread = null;
|
this.chat.activeChannel.activeThread = null;
|
||||||
this.chatStateManager.closeSidePanel();
|
this.chatStateManager.closeSidePanel();
|
||||||
|
|
||||||
if (!transition?.to?.name?.startsWith("chat.")) {
|
if (!transition?.to?.name?.startsWith("chat.")) {
|
||||||
|
@ -19,8 +19,4 @@ export default class ChatChannelRoute extends DiscourseRoute {
|
||||||
this.chat.updatePresence();
|
this.chat.updatePresence();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeModel() {
|
|
||||||
this.chatThreadsManager.resetCache();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,8 @@ import Collection from "../lib/collection";
|
||||||
* @implements {@ember/service}
|
* @implements {@ember/service}
|
||||||
*/
|
*/
|
||||||
export default class ChatApi extends Service {
|
export default class ChatApi extends Service {
|
||||||
|
@service chat;
|
||||||
@service chatChannelsManager;
|
@service chatChannelsManager;
|
||||||
@service chatThreadsManager;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a channel by its ID.
|
* Get a channel by its ID.
|
||||||
|
@ -40,7 +40,7 @@ export default class ChatApi extends Service {
|
||||||
*/
|
*/
|
||||||
thread(channelId, threadId) {
|
thread(channelId, threadId) {
|
||||||
return this.#getRequest(`/channels/${channelId}/threads/${threadId}`).then(
|
return this.#getRequest(`/channels/${channelId}/threads/${threadId}`).then(
|
||||||
(result) => this.chatThreadsManager.store(result.thread)
|
(result) => this.chat.activeChannel.threadsManager.store(result.thread)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,6 @@ export default class Chat extends Service {
|
||||||
@service site;
|
@service site;
|
||||||
@service chatChannelsManager;
|
@service chatChannelsManager;
|
||||||
@tracked activeChannel = null;
|
@tracked activeChannel = null;
|
||||||
@tracked activeThread = null;
|
|
||||||
cook = null;
|
cook = null;
|
||||||
presenceChannel = null;
|
presenceChannel = null;
|
||||||
sidebarActive = false;
|
sidebarActive = false;
|
||||||
|
|
Loading…
Reference in New Issue