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/
71 lines
1.7 KiB
JavaScript
71 lines
1.7 KiB
JavaScript
import { inject as service } from "@ember/service";
|
|
import { setOwner } from "@ember/application";
|
|
import Promise from "rsvp";
|
|
import ChatThread from "discourse/plugins/chat/discourse/models/chat-thread";
|
|
import { tracked } from "@glimmer/tracking";
|
|
import { TrackedObject } from "@ember-compat/tracked-built-ins";
|
|
import { popupAjaxError } from "discourse/lib/ajax-error";
|
|
|
|
/*
|
|
The ChatThreadsManager is responsible for managing the loaded chat threads
|
|
for a ChatChannel model.
|
|
|
|
It provides helpers to facilitate using and managing loaded threads instead of constantly
|
|
fetching them from the server.
|
|
*/
|
|
|
|
export default class ChatThreadsManager {
|
|
@service chatSubscriptionsManager;
|
|
@service chatApi;
|
|
@service currentUser;
|
|
@tracked _cached = new TrackedObject();
|
|
|
|
constructor(owner) {
|
|
setOwner(this, owner);
|
|
}
|
|
|
|
async find(channelId, threadId, options = { fetchIfNotFound: true }) {
|
|
const existingThread = this.#findStale(threadId);
|
|
if (existingThread) {
|
|
return Promise.resolve(existingThread);
|
|
} else if (options.fetchIfNotFound) {
|
|
return this.#find(channelId, threadId);
|
|
} else {
|
|
return Promise.resolve();
|
|
}
|
|
}
|
|
|
|
get threads() {
|
|
return Object.values(this._cached);
|
|
}
|
|
|
|
store(threadObject) {
|
|
let model = this.#findStale(threadObject.id);
|
|
|
|
if (!model) {
|
|
model = ChatThread.create(threadObject);
|
|
this.#cache(model);
|
|
}
|
|
|
|
return model;
|
|
}
|
|
|
|
async #find(channelId, threadId) {
|
|
return this.chatApi
|
|
.thread(channelId, threadId)
|
|
.catch(popupAjaxError)
|
|
.then((thread) => {
|
|
this.#cache(thread);
|
|
return thread;
|
|
});
|
|
}
|
|
|
|
#cache(thread) {
|
|
this._cached[thread.id] = thread;
|
|
}
|
|
|
|
#findStale(id) {
|
|
return this._cached[id];
|
|
}
|
|
}
|