This repository has been archived on 2023-03-18. You can view files and clone it, but cannot push or open issues or pull requests.
osr-discourse-src/app/assets/javascripts/discourse/app/pre-initializers/inject-discourse-objects.js
Jarek Radosz 19214aff18
DEV: Clean up all message bus subscriptions (#19268)
1. "What Goes Up Must Come Down" – if you subscribe to message bus, make sure you also unsubscribe
2. When you unsubscribe - remove only your subscription, not **all** subscriptions on given channel

Attempt #2. The first attempt tried to extend a core `@bound` method in new-user-narrative plugin which did not work. I reworked that plugin in the meantime. This new PR also cleans up message bus subscriptions in now core-merged chat plugin.
2022-12-12 16:32:25 +01:00

119 lines
3.9 KiB
JavaScript

import TopicTrackingState, {
startTracking,
} from "discourse/models/topic-tracking-state";
import DiscourseLocation from "discourse/lib/discourse-location";
import Session from "discourse/models/session";
import Site from "discourse/models/site";
import User from "discourse/models/user";
const ALL_TARGETS = ["controller", "component", "route", "model", "adapter"];
export function injectServiceIntoService({ app, property, specifier }) {
// app.inject doesn't allow implicit injection of services into services.
// However, we need to do it in order to convert our old service-like objects
// into true services, without breaking existing implicit injections.
// This hack will be removed when we remove implicit injections for the Ember 4.0 update.
// Supplying a specific injection with the same property name prevents the infinite
// which would be caused by injecting a service into itself
app.register("discourse:null", null, { instantiate: false });
app.inject(specifier, property, "discourse:null");
// Bypass the validation in `app.inject` by adding directly to the array
app.__registry__._typeInjections["service"] ??= [];
app.__registry__._typeInjections["service"].push({
property,
specifier,
});
}
export default {
name: "inject-discourse-objects",
after: "discourse-bootstrap",
initialize(container, app) {
const siteSettings = container.lookup("service:site-settings");
const currentUser = User.current();
// We can't use a 'real' service factory (i.e. services/current-user.js) because we need
// to register a null value for anon
app.register("service:current-user", currentUser, { instantiate: false });
this.topicTrackingState = TopicTrackingState.create({
messageBus: container.lookup("service:message-bus"),
siteSettings,
currentUser,
});
app.register("service:topic-tracking-state", this.topicTrackingState, {
instantiate: false,
});
const site = Site.current();
app.register("service:site", site, { instantiate: false });
const session = Session.current();
app.register("service:session", session, { instantiate: false });
app.register("location:discourse-location", DiscourseLocation);
ALL_TARGETS.forEach((t) => {
app.inject(t, "appEvents", "service:app-events");
app.inject(t, "pmTopicTrackingState", "service:pm-topic-tracking-state");
app.inject(t, "store", "service:store");
app.inject(t, "site", "service:site");
app.inject(t, "searchService", "service:search");
app.inject(t, "session", "service:session");
app.inject(t, "messageBus", "service:message-bus");
app.inject(t, "siteSettings", "service:site-settings");
app.inject(t, "topicTrackingState", "service:topic-tracking-state");
app.inject(t, "keyValueStore", "service:key-value-store");
});
injectServiceIntoService({
app,
property: "session",
specifier: "service:session",
});
injectServiceIntoService({
app,
property: "messageBus",
specifier: "service:message-bus",
});
injectServiceIntoService({
app,
property: "siteSettings",
specifier: "service:site-settings",
});
injectServiceIntoService({
app,
property: "topicTrackingState",
specifier: "service:topic-tracking-state",
});
injectServiceIntoService({
app,
property: "keyValueStore",
specifier: "service:key-value-store",
});
if (currentUser) {
["controller", "component", "route"].forEach((t) => {
app.inject(t, "currentUser", "service:current-user");
});
injectServiceIntoService({
app,
property: "currentUser",
specifier: "service:current-user",
});
}
startTracking(this.topicTrackingState);
},
teardown() {
// Manually call `willDestroy` as this isn't an actual `Service`
this.topicTrackingState.willDestroy();
},
};