DEV: refactors routes to simplify using outlet (#20179)

This work will allow us to have an {{outlet}} chat.channel route and use it for threads as a sidepanel.
This commit is contained in:
Joffrey JAFFEUX 2023-02-07 13:59:32 +01:00 committed by GitHub
parent f4b56ea455
commit b89df3ca9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 80 additions and 103 deletions

View File

@ -6,15 +6,18 @@ export default function () {
});
this.route("channel", { path: "/c/:channelTitle/:channelId" }, function () {
this.route("from-params", { path: "/" });
this.route("near-message", { path: "/:messageId" });
});
this.route("info", { path: "/info" }, function () {
this.route(
"channel.info",
{ path: "/c/:channelTitle/:channelId/info" },
function () {
this.route("about", { path: "/about" });
this.route("members", { path: "/members" });
this.route("settings", { path: "/settings" });
});
});
}
);
this.route("draft-channel", { path: "/draft-channel" });
this.route("browse", { path: "/browse" }, function () {

View File

@ -10,7 +10,7 @@
>
<div class="chat-channel-card__header">
<LinkTo
@route="chat.channel.from-params"
@route="chat.channel"
@models={{@channel.routeModels}}
class="chat-channel-card__name-container"
>

View File

@ -1,5 +1,5 @@
<LinkTo
@route="chat.channel.from-params"
@route="chat.channel"
@models={{@channel.routeModels}}
class={{concat-class
"chat-channel-row"

View File

@ -236,9 +236,9 @@ export default Component.extend({
this.set("view", DRAFT_CHANNEL_VIEW);
this.appEvents.trigger("chat:float-toggled", false);
return;
case "chat.channel.from-params":
case "chat.channel":
return this._openChannel(
route.parent.params.channelId,
route.params.channelId,
this._highlightCb(route.queryParams.messageId)
);
case "chat.channel.near-message":

View File

@ -15,7 +15,7 @@
{{/if}}
<LinkTo
@route={{this.infoTabRoute}}
@route="chat.channel.info"
@models={{this.chatChannel.routeModels}}
class="chat-channel-title-wrapper"
>

View File

@ -574,6 +574,8 @@ export default Component.extend({
return;
}
this.set("targetMessageId", messageId);
if (this.messageLookup[messageId]) {
// We have the message rendered. highlight and scrollTo
this.scrollToMessage(messageId, {
@ -582,7 +584,6 @@ export default Component.extend({
autoExpand: true,
});
} else {
this.set("targetMessageId", messageId);
this.fetchMessages(this.chatChannel);
}
},

View File

@ -3,5 +3,6 @@
@chatChannel={{this.chat.activeChannel}}
@onBackClick={{action "navigateToIndex"}}
@onSwitchChannel={{action "switchChannel"}}
@targetMessageId={{readonly @targetMessageId}}
/>
{{/if}}

View File

@ -5,6 +5,8 @@ import { inject as service } from "@ember/service";
export default class ChatChannelController extends Controller {
@service chat;
targetMessageId = null;
// Backwards-compatibility
queryParams = ["messageId"];

View File

@ -52,7 +52,7 @@ export default {
}
get route() {
return "chat.channel.from-params";
return "chat.channel";
}
get models() {
@ -215,7 +215,7 @@ export default {
}
get route() {
return "chat.channel.from-params";
return "chat.channel";
}
get models() {

View File

@ -0,0 +1,42 @@
import { inject as service } from "@ember/service";
export default function withChatChannel(extendedClass) {
return class WithChatChannel extends extendedClass {
@service chatChannelsManager;
@service chat;
@service router;
async model(params) {
return this.chatChannelsManager.find(params.channelId);
}
afterModel(model) {
this.controllerFor("chat-channel").set("targetMessageId", null);
this.chat.setActiveChannel(model);
let { messageId } = this.paramsFor(this.routeName);
// messageId query param backwards-compatibility
if (messageId) {
this.router.replaceWith(
"chat.channel",
...model.routeModels,
messageId
);
}
const { channelTitle } = this.paramsFor("chat.channel");
if (channelTitle && channelTitle !== model.slugifiedTitle) {
const nearMessageParams = this.paramsFor("chat.channel.near-message");
if (nearMessageParams.messageId) {
this.router.replaceWith(
"chat.channel.near-message",
...model.routeModels,
nearMessageParams.messageId
);
} else {
this.router.replaceWith("chat.channel", ...model.routeModels);
}
}
}
};
}

View File

@ -1,18 +0,0 @@
import DiscourseRoute from "discourse/routes/discourse";
import { inject as service } from "@ember/service";
export default class ChatChannelFromParamsRoute extends DiscourseRoute {
@service router;
async model() {
return this.modelFor("chat-channel");
}
afterModel(model) {
const { channelTitle } = this.paramsFor("chat.channel");
if (channelTitle !== model.slugifiedTitle) {
this.router.replaceWith("chat.channel.from-params", ...model.routeModels);
}
}
}

View File

@ -1,7 +1,9 @@
import DiscourseRoute from "discourse/routes/discourse";
import { inject as service } from "@ember/service";
import { ORIGINS } from "discourse/plugins/chat/discourse/services/chat-channel-info-route-origin-manager";
import withChatChannel from "./chat-channel-decorator";
@withChatChannel
export default class ChatChannelInfoRoute extends DiscourseRoute {
@service chatChannelInfoRouteOriginManager;

View File

@ -9,13 +9,8 @@ export default class ChatChannelLegacyRoute extends DiscourseRoute {
this.routeName
);
this.router.replaceWith(
"chat.channel.from-params",
channelTitle,
channelId,
{
queryParams: { messageId },
}
);
this.router.replaceWith("chat.channel", channelTitle, channelId, {
queryParams: { messageId },
});
}
}

View File

@ -1,41 +1,16 @@
import DiscourseRoute from "discourse/routes/discourse";
import { inject as service } from "@ember/service";
import { action } from "@ember/object";
import { schedule } from "@ember/runloop";
// This route is only here as a convience method for a clean `/c/:channelTitle/:channelId/:messageId` URL.
// It's not a real route, it just redirects to the real route after setting a param on the controller.
export default class ChatChannelNearMessage extends DiscourseRoute {
@service chat;
@service router;
async model() {
return this.modelFor("chat-channel");
}
afterModel(model) {
beforeModel() {
const channel = this.modelFor("chat-channel");
const { messageId } = this.paramsFor(this.routeName);
const { channelTitle } = this.paramsFor("chat.channel");
if (channelTitle !== model.slugifiedTitle) {
this.router.replaceWith(
"chat.channel.near-message",
...model.routeModels,
messageId
);
}
}
@action
didTransition() {
this.controllerFor("chat-channel").set("messageId", null);
const { messageId } = this.paramsFor(this.routeName);
const { channelId } = this.paramsFor("chat.channel");
if (channelId && messageId) {
schedule("afterRender", () => {
this.chat.openChannelAtMessage(channelId, messageId);
});
}
return true;
this.controllerFor("chat-channel").set("targetMessageId", messageId);
this.router.replaceWith("chat.channel", ...channel.routeModels);
}
}

View File

@ -1,27 +1,5 @@
import DiscourseRoute from "discourse/routes/discourse";
import { inject as service } from "@ember/service";
import withChatChannel from "./chat-channel-decorator";
export default class ChatChannelRoute extends DiscourseRoute {
@service chatChannelsManager;
@service chat;
@service router;
async model(params) {
return this.chatChannelsManager.find(params.channelId);
}
afterModel(model) {
this.chat.setActiveChannel(model);
const { messageId } = this.paramsFor(this.routeName);
// messageId query param backwards-compatibility
if (messageId) {
this.router.replaceWith(
"chat.channel.near-message",
...model.routeModels,
messageId
);
}
}
}
@withChatChannel
export default class ChatChannelRoute extends DiscourseRoute {}

View File

@ -22,7 +22,7 @@ export default class ChatRoute extends DiscourseRoute {
const INTERCEPTABLE_ROUTES = [
"chat.channel",
"chat.channel.from-params",
"chat.channel.index",
"chat.channel.near-message",
"chat.channel-legacy",
"chat",

View File

@ -277,7 +277,7 @@ export default class Chat extends Service {
async _openFoundChannelAtMessage(channel, messageId = null) {
if (
(this.router.currentRouteName === "chat.channel.from-params" ||
(this.router.currentRouteName === "chat.channel" ||
this.router.currentRouteName === "chat.channel.near-message") &&
this.activeChannel?.id === channel.id
) {
@ -300,10 +300,7 @@ export default class Chat extends Service {
messageId
);
} else {
return this.router.transitionTo(
"chat.channel.from-params",
...channel.routeModels
);
return this.router.transitionTo("chat.channel", ...channel.routeModels);
}
} else {
this._fireOpenFloatAppEvent(channel, messageId);

View File

@ -12,7 +12,7 @@
</LinkTo>
{{else}}
<LinkTo
@route="chat.channel.from-params"
@route="chat.channel"
@models={{this.model.routeModels}}
class="chat-full-page-header__back-btn no-text btn-flat btn"
title={{i18n "chat.channel_info.back_to_channel"}}

View File

@ -1 +1 @@
{{outlet}}
<FullPageChat @targetMessageId={{this.targetMessageId}} />