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/components/mobile-nav.js
David Taylor 1844bde57c
FIX: Allow mobile-nav to work without loading transitions (#12184)
Previously, the `{{mobile-nav}}` component required a `currentRouteName` property, passed from the router service. It would observe changes in this property, and update the UI accordingly.

If we change between routes which have the same `currentRouteName` (e.g. two different group message inboxes), then the `currentRouteName` does not change and does not trigger the observer. Currently in core, we are relying on the fact that currentRouteName temporarily enters a `.loading` substate during a transition. This will change when we remove the loading substate in the near future.

This commit refactors `{{mobile-nav}}` to inject the router directly, and use the `routeDidChange` event instead of an observer. The change is backwards compatible, but plugins passing the old `currentPath` property will be shown a deprecation notice.
2021-02-23 11:16:40 +00:00

82 lines
2.0 KiB
JavaScript

import { on } from "discourse-common/utils/decorators";
import Component from "@ember/component";
import { next } from "@ember/runloop";
import { inject as service } from "@ember/service";
import deprecated from "discourse-common/lib/deprecated";
export default Component.extend({
@on("init")
_init() {
if (!this.get("site.mobileView")) {
let classes = this.desktopClass;
if (classes) {
classes = classes.split(" ");
this.set("classNames", classes);
}
}
if (this.currentPath) {
deprecated("{{mobile-nav}} no longer requires the currentPath property", {
since: "2.7.0.beta4",
});
}
},
tagName: "ul",
selectedHtml: null,
classNames: ["mobile-nav"],
router: service(),
currentRouteChanged() {
this.set("expanded", false);
next(() => this._updateSelectedHtml());
},
_updateSelectedHtml() {
if (!this.element || this.isDestroying || this.isDestroyed) {
return;
}
const active = this.element.querySelector(".active");
if (active && active.innerHTML) {
this.set("selectedHtml", active.innerHTML);
}
},
didInsertElement() {
this._super(...arguments);
this._updateSelectedHtml();
this.router.on("routeDidChange", this, this.currentRouteChanged);
},
willDestroyElement() {
this.router.off("routeDidChange", this, this.currentRouteChanged);
},
actions: {
toggleExpanded() {
this.toggleProperty("expanded");
next(() => {
if (this.expanded) {
$(window)
.off("click.mobile-nav")
.on("click.mobile-nav", (e) => {
if (!this.element || this.isDestroying || this.isDestroyed) {
return;
}
const expander = this.element.querySelector(".expander");
if (expander && e.target !== expander) {
this.set("expanded", false);
$(window).off("click.mobile-nav");
}
});
}
});
},
},
});