REFACTOR: handles every chat resource as an URL (#18961)

- Note this is also tweaking the UI a little bit as we are now using links/buttons in the header as needed
- It disables the find ideal channel in drawer mode, if loading `/chat` in drawer mode it will either reopen at the last position or just stay on index
This commit is contained in:
Joffrey JAFFEUX 2022-11-11 06:39:15 +01:00 committed by GitHub
parent 4db5525d25
commit 66130dc8c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
60 changed files with 639 additions and 759 deletions

View File

@ -4,15 +4,14 @@ import { action, computed } from "@ember/object";
import { schedule } from "@ember/runloop";
import { inject as service } from "@ember/service";
import { and, empty, reads } from "@ember/object/computed";
import { DRAFT_CHANNEL_VIEW } from "discourse/plugins/chat/discourse/services/chat";
export default class ChannelsList extends Component {
@service chat;
@service router;
@service chatStateManager;
tagName = "";
inSidebar = false;
toggleSection = null;
onSelect = null;
@reads("chat.publicChannels.[]") publicChannels;
@reads("chat.directMessageChannels.[]") directMessageChannels;
@empty("publicChannels") publicChannelsEmpty;
@ -80,24 +79,6 @@ export default class ChannelsList extends Component {
}`;
}
@action
browseChannels() {
this.router.transitionTo("chat.browse");
return false;
}
@action
startCreatingDmChannel() {
if (
this.site.mobileView ||
this.router.currentRouteName.startsWith("chat.")
) {
this.router.transitionTo("chat.draft-channel");
} else {
this.appEvents.trigger("chat:open-view", DRAFT_CHANNEL_VIEW);
}
}
@action
toggleChannelSection(section) {
this.toggleSection(section);

View File

@ -87,11 +87,6 @@ export default class ChatBrowseView extends Component {
showModal("create-channel");
}
@action
returnToChannelsList() {
return this.router.transitionTo("chat.index");
}
@bind
filterChannels(filter) {
this.canLoadMore = true;

View File

@ -1,8 +1,6 @@
import Component from "@ember/component";
import I18n from "I18n";
import discourseComputed from "discourse-common/utils/decorators";
import getURL from "discourse-common/lib/get-url";
import { action } from "@ember/object";
import { equal } from "@ember/object/computed";
import { inject as service } from "@ember/service";
import { CHATABLE_TYPES } from "discourse/plugins/chat/discourse/models/chat-channel";
@ -12,7 +10,6 @@ export default Component.extend({
router: service(),
chat: service(),
channel: null,
switchChannel: null,
isDirectMessageRow: equal(
"channel.chatable_type",
CHATABLE_TYPES.directMessageChannel
@ -75,52 +72,6 @@ export default Component.extend({
);
},
@action
handleNewWindow(event) {
// Middle mouse click
if (event.which === 2) {
window
.open(
getURL(`/chat/channel/${this.channel.id}/${this.channel.title}`),
"_blank"
)
.focus();
}
},
@action
handleSwitchChannel(event) {
if (this.switchChannel) {
this.switchChannel(this.channel);
event.preventDefault();
}
},
@action
handleClick(event) {
if (event.target.classList.contains("chat-channel-leave-btn")) {
return true;
}
if (
event.target.classList.contains("chat-channel-settings-btn") ||
event.target.parentElement.classList.contains("select-kit-header-wrapper")
) {
return;
}
this.handleSwitchChannel(event);
},
@action
handleKeyUp(event) {
if (event.key !== "Enter") {
return;
}
this.handleSwitchChannel(event);
},
@discourseComputed("channel.chatable_type")
leaveChatTitle() {
if (this.channel.isDirectMessageChannel) {

View File

@ -9,11 +9,11 @@ import UppyUploadMixin from "discourse/mixins/uppy-upload";
export default Component.extend(UppyUploadMixin, {
classNames: ["chat-composer-uploads"],
mediaOptimizationWorker: service(),
chatStateManager: service(),
id: "chat-composer-uploader",
type: "chat-composer",
uploads: null,
useMultipartUploadsIfAvailable: true,
fullPage: false,
init() {
this._super(...arguments);
@ -66,7 +66,7 @@ export default Component.extend(UppyUploadMixin, {
_uploadDropTargetOptions() {
let targetEl;
if (this.fullPage) {
if (this.chatStateManager.isFullPage) {
targetEl = document.querySelector(".full-page-chat");
} else {
targetEl = document.querySelector(

View File

@ -37,8 +37,8 @@ export default Component.extend(TextareaTextManipulation, {
userSilenced: readOnly("details.user_silenced"),
chatEmojiReactionStore: service("chat-emoji-reaction-store"),
chatEmojiPickerManager: service("chat-emoji-picker-manager"),
chatStateManager: service("chat-state-manager"),
editingMessage: null,
fullPage: false,
onValueChange: null,
timer: null,
value: "",
@ -63,7 +63,7 @@ export default Component.extend(TextareaTextManipulation, {
return picker.opened && picker.context === "chat-composer";
},
@discourseComputed("fullPage")
@discourseComputed("chatStateManager.isFullPage")
fileUploadElementId(fullPage) {
return fullPage ? "chat-full-page-uploader" : "chat-widget-uploader";
},

View File

@ -41,7 +41,6 @@ const FUTURE = "future";
export default Component.extend({
classNameBindings: [":chat-live-pane", "sendingLoading", "loading"],
chatChannel: null,
fullPage: false,
registeredChatChannelId: null, // ?Number
loading: false,
loadingMorePast: false,
@ -73,8 +72,7 @@ export default Component.extend({
router: service(),
chatEmojiPickerManager: service(),
chatComposerPresenceManager: service(),
chatPreferredMode: service(),
fullPageChat: service(),
chatStateManager: service(),
getCachedChannelDetails: null,
clearCachedChannelDetails: null,
@ -1264,11 +1262,14 @@ export default Component.extend({
},
@action
onCloseFullScreen(channel) {
this.chatPreferredMode.setDrawer();
onCloseFullScreen() {
this.chatStateManager.prefersDrawer();
this.router.replaceWith(this.fullPageChat.exit()).then(() => {
this.appEvents.trigger("chat:open-channel", channel);
this.router.transitionTo(this.chatStateManager.lastKnownAppURL).then(() => {
this.appEvents.trigger(
"chat:open-url",
this.chatStateManager.lastKnownChatURL
);
});
},

View File

@ -10,7 +10,7 @@ const MSG_ACTIONS_VERTICAL_PADDING = -15;
export default Component.extend({
tagName: "",
chatPreferredMode: service(),
chatStateManager: service(),
messageActions: null,

View File

@ -21,6 +21,7 @@ export default Component.extend({
focusedUser: null,
chat: service(),
router: service(),
chatStateManager: service(),
isLoading: false,
onSwitchChannel: null,

View File

@ -1,6 +1,5 @@
import Component from "@ember/component";
import discourseComputed, { observes } from "discourse-common/utils/decorators";
import getURL from "discourse-common/lib/get-url";
import { action } from "@ember/object";
import {
CHAT_VIEW,
@ -18,7 +17,7 @@ export default Component.extend({
classNameBindings: [":topic-chat-float-container", "hidden"],
chat: service(),
router: service(),
chatPreferredMode: service(),
chatStateManager: service(),
hidden: true,
loading: false,
expanded: true, // TODO - false when not first-load topic
@ -35,15 +34,8 @@ export default Component.extend({
}
this._checkSize();
this.appEvents.on("chat:navigated-to-full-page", this, "close");
this.appEvents.on("chat:open-view", this, "openView");
this.appEvents.on("chat:toggle-open", this, "toggleChat");
this.appEvents.on("chat:open-url", this, "openURL");
this.appEvents.on("chat:toggle-close", this, "close");
this.appEvents.on(
"chat:open-channel-for-chatable",
this,
"openChannelForChatable"
);
this.appEvents.on("chat:open-channel", this, "switchChannel");
this.appEvents.on(
"chat:open-channel-at-message",
@ -70,15 +62,8 @@ export default Component.extend({
}
if (this.appEvents) {
this.appEvents.off("chat:open-view", this, "openView");
this.appEvents.off("chat:navigated-to-full-page", this, "close");
this.appEvents.off("chat:toggle-open", this, "toggleChat");
this.appEvents.off("chat:open-url", this, "openURL");
this.appEvents.off("chat:toggle-close", this, "close");
this.appEvents.off(
"chat:open-channel-for-chatable",
this,
"openChannelForChatable"
);
this.appEvents.off("chat:open-channel", this, "switchChannel");
this.appEvents.off(
"chat:open-channel-at-message",
@ -116,14 +101,6 @@ export default Component.extend({
this.appEvents.trigger("chat:rerender-header");
},
async openChannelForChatable(channel) {
if (!channel) {
return;
}
this.switchChannel(channel);
},
@discourseComputed("expanded")
topLineClass(expanded) {
const baseClass = "topic-chat-drawer-header__top-line";
@ -225,38 +202,45 @@ export default Component.extend({
},
@action
openView(view) {
this.setProperties({
hidden: false,
expanded: true,
view,
});
openURL(URL = null) {
this.set("hidden", false);
this.set("expanded", true);
this.appEvents.trigger("chat:float-toggled", false);
this.chatStateManager.storeChatURL(URL);
const route = this._buildRouteFromURL(
URL || this.chatStateManager.lastKnownChatURL
);
switch (route.name) {
case "chat":
this.chat.setActiveChannel(null);
this.set("view", LIST_VIEW);
this.appEvents.trigger("chat:float-toggled", false);
return;
case "chat.draft-channel":
this.chat.setActiveChannel(null);
this.set("view", DRAFT_CHANNEL_VIEW);
this.appEvents.trigger("chat:float-toggled", false);
return;
case "chat.channel":
return this.chat
.getChannelBy("id", route.params.channelId)
.then((channel) => {
this.chat.setActiveChannel(channel);
this.set("view", CHAT_VIEW);
this.appEvents.trigger("chat:float-toggled", false);
});
}
},
@action
openInFullPage(e) {
this.chatPreferredMode.setFullPage();
const channel = this.chat.activeChannel;
this.set("expanded", false);
this.set("hidden", true);
openInFullPage() {
this.chatStateManager.storeAppURL();
this.chatStateManager.prefersFullPage();
this.chat.setActiveChannel(null);
if (!channel) {
return this.router.transitionTo("chat");
}
if (e.which === 2) {
// Middle mouse click
window
.open(getURL(`/chat/channel/${channel.id}/${channel.title}`), "_blank")
.focus();
return false;
}
this.chat.openChannel(channel);
return this.router.transitionTo(this.chatStateManager.lastKnownChatURL);
},
@action
@ -267,42 +251,11 @@ export default Component.extend({
@action
close() {
this.setProperties({
hidden: true,
expanded: false,
});
this.chat.setActiveChannel(null);
this.set("hidden", true);
this.set("expanded", false);
this.appEvents.trigger("chat:float-toggled", this.hidden);
},
@action
toggleChat() {
this.set("hidden", !this.hidden);
this.appEvents.trigger("chat:float-toggled", this.hidden);
if (this.hidden) {
return this.chat.setActiveChannel(null);
} else {
this.set("expanded", true);
this.appEvents.trigger("chat:toggle-expand", this.expanded);
if (this.chat.activeChannel) {
// Channel was previously open, so after expand we are done.
return this.chat.setActiveChannel(null);
}
}
// Look for DM channel with unread, and fallback to public channel with unread
this.chat.getIdealFirstChannelId().then((channelId) => {
if (channelId) {
this.chat.getChannelBy("id", channelId).then((channel) => {
this.switchChannel(channel);
});
} else {
// No channels with unread messages. Fetch channel index.
this.fetchChannels();
}
});
},
@action
refreshChannels() {
if (this.view === LIST_VIEW) {
@ -341,11 +294,41 @@ export default Component.extend({
this.chat.setActiveChannel(channel);
if (!channel) {
this.openView(LIST_VIEW);
const URL = this._buildURLFromState(LIST_VIEW);
this.openURL(URL);
return;
}
this.openView(CHAT_VIEW);
const URL = this._buildURLFromState(CHAT_VIEW, channel);
this.openURL(URL);
});
},
_buildRouteFromURL(URL) {
let route = this.router.recognize(URL || "/");
// ember might recognize the index subroute
if (route.localName === "index") {
route = route.parent;
}
return route;
},
_buildURLFromState(view, channel = null) {
switch (view) {
case LIST_VIEW:
return "/chat";
case DRAFT_CHANNEL_VIEW:
return "/chat/draft-channel";
case CHAT_VIEW:
if (channel) {
return `/chat/channel/${channel.id}/${channel.slug || "-"}`;
} else {
return "/chat";
}
default:
return "/chat";
}
},
});

View File

@ -14,7 +14,9 @@ export default {
return;
}
const router = container.lookup("service:router");
const appEvents = container.lookup("service:app-events");
const chatStateManager = container.lookup("service:chat-state-manager");
const openChannelSelector = (e) => {
e.preventDefault();
e.stopPropagation();
@ -77,7 +79,9 @@ export default {
}
event.preventDefault();
event.stopPropagation();
appEvents.trigger("chat:toggle-open", event);
chatStateManager.prefersDrawer();
router.transitionTo(chatStateManager.lastKnownChatURL || "chat");
};
const closeChatDrawer = (event) => {

View File

@ -4,7 +4,6 @@ import { withPluginApi } from "discourse/lib/plugin-api";
import I18n from "I18n";
import { bind } from "discourse-common/utils/decorators";
import { tracked } from "@glimmer/tracking";
import { DRAFT_CHANNEL_VIEW } from "discourse/plugins/chat/discourse/services/chat";
import { avatarUrl, escapeExpression } from "discourse/lib/utilities";
import { dasherize } from "@ember/string";
import { emojiUnescape } from "discourse/lib/text";
@ -136,19 +135,18 @@ export default {
return;
}
this.chatService = container.lookup("service:chat");
this.chatService.appEvents.on(
"chat:refresh-channels",
this._refreshChannels
);
this.router = container.lookup("service:router");
this.appEvents = container.lookup("service:app-events");
this.appEvents.on("chat:refresh-channels", this._refreshChannels);
this._refreshChannels();
}
@bind
willDestroy() {
if (!this.chatService) {
if (!this.appEvents) {
return;
}
this.chatService.appEvents.off(
this.appEvents.off(
"chat:refresh-channels",
this._refreshChannels
);
@ -187,9 +185,7 @@ export default {
{
id: "browseChannels",
title: I18n.t("chat.channels_list_popup.browse"),
action: () => {
this.chatService.router.transitionTo("chat.browse");
},
action: () => this.router.transitionTo("chat.browse.open"),
},
];
}
@ -336,7 +332,9 @@ export default {
}
get hoverAction() {
return () => {
return (event) => {
event.stopPropagation();
event.preventDefault();
this.chatService.unfollowChannel(this.channel);
};
}
@ -371,6 +369,7 @@ export default {
const SidebarChatDirectMessagesSection = class extends BaseCustomSidebarSection {
@service site;
@service router;
@tracked sectionLinks = [];
@tracked userCanDirectMessage =
this.chatService.userCanDirectMessage;
@ -440,19 +439,7 @@ export default {
id: "startDm",
title: I18n.t("chat.direct_messages.new"),
action: () => {
if (
this.site.mobileView ||
this.chatService.router.currentRouteName.startsWith("")
) {
this.chatService.router.transitionTo(
"chat.draft-channel"
);
} else {
this.appEvents.trigger(
"chat:open-view",
DRAFT_CHANNEL_VIEW
);
}
this.router.transitionTo("chat.draft-channel");
},
},
];

View File

@ -8,8 +8,7 @@ import slugifyChannel from "discourse/plugins/chat/discourse/lib/slugify-channel
export default class ChatChannelRoute extends DiscourseRoute {
@service chat;
@service fullPageChat;
@service chatPreferredMode;
@service router;
async model(params) {
let [chatChannel, channels] = await Promise.all([
@ -38,13 +37,12 @@ export default class ChatChannelRoute extends DiscourseRoute {
}
afterModel(model) {
this.appEvents.trigger("chat:navigated-to-full-page");
this.chat.setActiveChannel(model?.chatChannel);
const queryParams = this.paramsFor(this.routeName);
const slug = slugifyChannel(model.chatChannel);
if (queryParams?.channelTitle !== slug) {
this.replaceWith("chat.channel.index", model.chatChannel.id, slug);
this.router.replaceWith("chat.channel.index", model.chatChannel.id, slug);
}
}

View File

@ -4,46 +4,59 @@ import { defaultHomepage } from "discourse/lib/utilities";
import { inject as service } from "@ember/service";
import { scrollTop } from "discourse/mixins/scroll-top";
import { schedule } from "@ember/runloop";
import { DRAFT_CHANNEL_VIEW } from "discourse/plugins/chat/discourse/services/chat";
import { action } from "@ember/object";
export default class ChatRoute extends DiscourseRoute {
@service chat;
@service router;
@service fullPageChat;
@service chatPreferredMode;
@service chatStateManager;
titleToken() {
return I18n.t("chat.title_capitalized");
}
beforeModel(transition) {
if (
transition.from && // don't intercept when directly loading chat
this.chatPreferredMode.isDrawer
) {
if (transition.intent?.name === "chat.channel") {
transition.abort();
const id = transition.intent.contexts[0];
return this.chat.getChannelBy("id", id).then((channel) => {
this.appEvents.trigger("chat:open-channel", channel);
});
}
if (transition.intent?.name === "chat.draft-channel") {
transition.abort();
this.appEvents.trigger("chat:open-view", DRAFT_CHANNEL_VIEW);
return;
}
}
if (!this.chat.userCanChat) {
return this.router.transitionTo(`discovery.${defaultHomepage()}`);
}
this.fullPageChat.enter(this.router.currentURL);
const INTERCEPTABLE_ROUTES = [
"chat.channel.index",
"chat.channel",
"chat",
"chat.index",
"chat.draft-channel",
];
if (
transition.from && // don't intercept when directly loading chat
this.chatStateManager.isDrawerPreferred &&
INTERCEPTABLE_ROUTES.includes(transition.targetName)
) {
transition.abort();
let URL = transition.intent.url;
if (
transition.targetName === "chat.channel.index" ||
transition.targetName === "chat.channel"
) {
URL ??= this.router.urlFor(
transition.targetName,
...transition.intent.contexts
);
} else {
URL ??= this.router.urlFor(transition.targetName);
}
this.appEvents.trigger("chat:open-url", URL);
return;
}
this.appEvents.trigger("chat:toggle-close");
}
activate() {
this.chatStateManager.storeAppURL();
this.chat.updatePresence();
schedule("afterRender", () => {
@ -53,7 +66,6 @@ export default class ChatRoute extends DiscourseRoute {
}
deactivate() {
this.fullPageChat.exit();
this.chat.setActiveChannel(null);
schedule("afterRender", () => {
@ -62,4 +74,11 @@ export default class ChatRoute extends DiscourseRoute {
scrollTop();
});
}
@action
willTransition(transition) {
if (!transition?.to?.name?.startsWith("chat.")) {
this.chatStateManager.storeChatURL();
}
}
}

View File

@ -1,35 +0,0 @@
import KeyValueStore from "discourse/lib/key-value-store";
import Service from "@ember/service";
import Site from "discourse/models/site";
const PREFERRED_MODE_KEY = "preferred_mode";
const PREFERRED_MODE_STORE_NAMESPACE = "discourse_chat_";
const FULL_PAGE_CHAT = "FULL_PAGE_CHAT";
const DRAWER_CHAT = "DRAWER_CHAT";
export default class ChatPreferredMode extends Service {
_store = new KeyValueStore(PREFERRED_MODE_STORE_NAMESPACE);
setFullPage() {
this._store.setObject({ key: PREFERRED_MODE_KEY, value: FULL_PAGE_CHAT });
}
setDrawer() {
this._store.setObject({ key: PREFERRED_MODE_KEY, value: DRAWER_CHAT });
}
get isFullPage() {
return !!(
Site.currentProp("mobileView") ||
this._store.getObject(PREFERRED_MODE_KEY) === FULL_PAGE_CHAT
);
}
get isDrawer() {
return !!(
!Site.currentProp("mobileView") &&
(!this._store.getObject(PREFERRED_MODE_KEY) ||
this._store.getObject(PREFERRED_MODE_KEY) === DRAWER_CHAT)
);
}
}

View File

@ -0,0 +1,73 @@
import Service, { inject as service } from "@ember/service";
import { defaultHomepage } from "discourse/lib/utilities";
import { tracked } from "@glimmer/tracking";
import KeyValueStore from "discourse/lib/key-value-store";
import Site from "discourse/models/site";
const PREFERRED_MODE_KEY = "preferred_mode";
const PREFERRED_MODE_STORE_NAMESPACE = "discourse_chat_";
const FULL_PAGE_CHAT = "FULL_PAGE_CHAT";
const DRAWER_CHAT = "DRAWER_CHAT";
export default class ChatStateManager extends Service {
@service router;
@tracked _chatURL = null;
@tracked _appURL = null;
_store = new KeyValueStore(PREFERRED_MODE_STORE_NAMESPACE);
reset() {
this._store.remove(PREFERRED_MODE_KEY);
this._chatURL = null;
this._appURL = null;
}
prefersFullPage() {
this._store.setObject({ key: PREFERRED_MODE_KEY, value: FULL_PAGE_CHAT });
}
prefersDrawer() {
this._store.setObject({ key: PREFERRED_MODE_KEY, value: DRAWER_CHAT });
}
get isFullPagePreferred() {
return !!(
Site.currentProp("mobileView") ||
this._store.getObject(PREFERRED_MODE_KEY) === FULL_PAGE_CHAT
);
}
get isDrawerPreferred() {
return !!(
!this.isFullPagePreferred ||
(!Site.currentProp("mobileView") &&
(!this._store.getObject(PREFERRED_MODE_KEY) ||
this._store.getObject(PREFERRED_MODE_KEY) === DRAWER_CHAT))
);
}
get isFullPage() {
return this.router.currentRouteName?.startsWith("chat");
}
storeAppURL(URL = null) {
this._appURL = URL || this.router.currentURL;
}
storeChatURL(URL = null) {
this._chatURL = URL || this.router.currentURL;
}
get lastKnownAppURL() {
let url = this._appURL;
if (!url || url === "/") {
url = this.router.urlFor(`discovery.${defaultHomepage()}`);
}
return url;
}
get lastKnownChatURL() {
return this._chatURL || "/chat";
}
}

View File

@ -35,8 +35,7 @@ const READ_INTERVAL = 1000;
export default class Chat extends Service {
@service appEvents;
@service chatNotificationManager;
@service chatPreferredMode;
@service fullPageChat;
@service chatStateManager;
@service presence;
@service router;
@service site;
@ -177,7 +176,7 @@ export default class Chat extends Service {
updatePresence() {
next(() => {
if (this.fullPageChat.isActive || this.chatOpen) {
if (this.chatStateManager.isFullPage || this.chatOpen) {
this.presenceChannel.enter({ activeOptions: CHAT_ONLINE_OPTIONS });
} else {
this.presenceChannel.leave();
@ -526,9 +525,9 @@ export default class Chat extends Service {
this.setActiveChannel(channel);
if (
this.fullPageChat.isActive ||
this.chatStateManager.isFullPage ||
this.site.mobileView ||
this.chatPreferredMode.isFullPage
this.chatStateManager.isFullPagePreferred
) {
const queryParams = messageId ? { messageId } : {};
@ -748,7 +747,7 @@ export default class Chat extends Service {
this._unsubscribeFromChatChannel(channel);
this.stopTrackingChannel(channel);
if (channel.isDirectMessageChannel) {
if (channel === this.activeChannel && channel.isDirectMessageChannel) {
this.router.transitionTo("chat");
}
});

View File

@ -1,35 +0,0 @@
import Service, { inject as service } from "@ember/service";
import { defaultHomepage } from "discourse/lib/utilities";
export default class FullPageChat extends Service {
@service router;
_previousURL = null;
_isActive = false;
enter(previousURL) {
this._previousURL = previousURL;
this._isActive = true;
}
exit() {
if (this.isDestroyed || this.isDestroying) {
return;
}
this._isActive = false;
let previousURL = this._previousURL;
if (!previousURL || previousURL === "/") {
previousURL = this.router.urlFor(`discovery.${defaultHomepage()}`);
}
this._previousURL = null;
return previousURL;
}
get isActive() {
return this._isActive;
}
}

View File

@ -1 +1 @@
<FullPageChat @chatChannel={{this.model.chatChannel}} @refreshModel={{route-action "refreshModel"}} />
<FullPageChat @refreshModel={{route-action "refreshModel"}} />

View File

@ -1,29 +1,26 @@
<div class="channel-info">
<div class="chat-full-page-header">
{{#if this.chatChannelInfoRouteOriginManager.isBrowse}}
<LinkTo @route="chat.browse" class="channel-info__back-btn">
{{d-icon "chevron-left"}}
<span>
{{i18n "chat.channel_info.back_to_all_channels"}}
</span>
</LinkTo>
{{else}}
<LinkTo
@route="chat.channel"
@models={{array
this.model.chatChannel.id
(slugify-channel this.model.chatChannel)
}}
class="channel-info__back-btn"
>
{{d-icon "chevron-left"}}
<span>
{{i18n "chat.channel_info.back_to_channel"}}
</span>
</LinkTo>
{{/if}}
<div class="chat-channel-header-details">
<div class="chat-full-page-header__left-actions">
{{#if this.chatChannelInfoRouteOriginManager.isBrowse}}
<LinkTo @route="chat.browse" class="chat-full-page-header__back-btn no-text btn-flat btn" title={{i18n "chat.channel_info.back_to_all_channel"}}>
{{d-icon "chevron-left"}}
</LinkTo>
{{else}}
<LinkTo
@route="chat.channel"
@models={{array
this.model.chatChannel.id
(slugify-channel this.model.chatChannel)
}}
class="chat-full-page-header__back-btn no-text btn-flat btn"
title={{i18n "chat.channel_info.back_to_channel"}}
>
{{d-icon "chevron-left"}}
</LinkTo>
{{/if}}
</div>
<ChatChannelTitle @channel={{this.model.chatChannel}} />
</div>
</div>

View File

@ -1,11 +1,7 @@
{{#if this.showMobileDirectMessageButton}}
<DButton
@class="btn-flat new-dm keep-mobile-sidebar-open btn-floating"
@icon="plus"
@action={{action "startCreatingDmChannel"}}
@title={{this.createDirectMessageChannelLabel}}
@disabled={{not this.canCreateDirectMessageChannel}}
/>
{{#if (and this.showMobileDirectMessageButton this.canCreateDirectMessageChannel)}}
<LinkTo @route="chat.draft-channel" class="btn-flat open-draft-channel-page-btn keep-mobile-sidebar-open btn-floating" title={{i18n this.createDirectMessageChannelLabel}}>
{{d-icon "plus"}}
</LinkTo>
{{/if}}
<div
@ -30,11 +26,9 @@
{{/if}}
<span class="channel-title">{{i18n "chat.chat_channels"}}</span>
<DButton
@action={{action "browseChannels"}}
@icon="pencil-alt"
@class="btn-flat edit-channel-membership-btn title-action"
/>
<LinkTo @route="chat.browse" class="btn no-text btn-flat open-browse-page-btn title-action" title={{i18n "chat.channels_list_popup.browse"}}>
{{d-icon "pencil-alt"}}
</LinkTo>
</div>
<div id="public-channels" class={{this.publicChannelClasses}}>
@ -49,7 +43,6 @@
{{#each this.publicChannels as |channel|}}
<ChatChannelRow
@channel={{channel}}
@switchChannel={{this.onSelect}}
@options={{hash settingsButton=true}}
/>
{{/each}}
@ -82,14 +75,10 @@
{{/if}}
<span class="channel-title">{{i18n "chat.direct_messages.title"}}</span>
{{#if this.site.desktopView}}
<DButton
@class="btn-flat new-dm keep-mobile-sidebar-open"
@icon="plus"
@action={{action "startCreatingDmChannel"}}
@title={{this.createDirectMessageChannelLabel}}
@disabled={{not this.canCreateDirectMessageChannel}}
/>
{{#if (and this.canCreateDirectMessageChannel (not this.showMobileDirectMessageButton))}}
<LinkTo @route="chat.draft-channel" class="btn no-text btn-flat open-draft-channel-page-btn" title={{i18n this.createDirectMessageChannelLabel}}>
{{d-icon "plus"}}
</LinkTo>
{{/if}}
</div>
{{/if}}
@ -98,7 +87,6 @@
{{#each this.sortedDirectMessageChannels as |channel|}}
<ChatChannelRow
@channel={{channel}}
@switchChannel={{this.onSelect}}
@options={{hash leaveButton=true}}
/>
{{/each}}

View File

@ -4,27 +4,26 @@
{{/in-element}}
{{/if}}
<div class="chat-browse-view">
<div class="chat-browse-view__header">
{{#if this.site.mobileView}}
<DButton
@action={{action "returnToChannelsList"}}
@icon="chevron-left"
@class="chat-browse-view__back"
@title="chat.browse.back"
/>
{{/if}}
<h1 class="chat-browse-view__title">{{i18n "chat.browse.title"}}</h1>
{{#if this.currentUser.staff}}
<DButton
@action={{action "createChannel"}}
@icon="plus"
@class="new-channel-btn"
@label={{if this.site.desktopView "chat.create_channel.title"}}
/>
{{/if}}
</div>
<div class="chat-browse-view__header chat-full-page-header">
{{#if this.site.mobileView}}
<LinkTo @route="chat.index" class="chat-full-page-header__back-btn no-text btn-flat btn" title={{i18n "chat.browse.back"}}>
{{d-icon "chevron-left"}}
</LinkTo>
{{/if}}
<span class="chat-browse-view__title">{{i18n "chat.browse.title"}}</span>
{{#if this.currentUser.staff}}
<DButton
@action={{action "createChannel"}}
@icon="plus"
@class={{concat-class "new-channel-btn" (if this.site.mobileView "btn-flat")}}
@label={{if this.site.desktopView "chat.create_channel.title"}}
/>
{{/if}}
</div>
<div class="chat-browse-view">
<div class="chat-browse-view__actions">
<nav>
<ul class="nav-pills chat-browse-view__filters">

View File

@ -1,13 +1,4 @@
<div
id="chat-channel-row-{{this.channel.id}}"
class={{this.rowClassNames}}
{{on "click" this.handleClick}}
{{on "keyup" this.handleKeyUp}}
{{on "mouseup" this.handleNewWindow}}
role="button"
tabindex="0"
data-chat-channel-id={{this.channel.id}}
>
<LinkTo @route="chat.channel" @models={{array this.channel.id (or this.channel.slug "-")}} class={{this.rowClassNames}} id={{concat "chat-channel-row-" this.channel.id}} tabindex="0" data-chat-channel-id={{this.channel.id}}>
<ChatChannelTitle @channel={{this.channel}} @unreadIndicator={{true}} />
{{#if this.showUserStatus}}
@ -25,4 +16,4 @@
}}
/>
{{/if}}
</div>
</LinkTo>

View File

@ -45,7 +45,7 @@
</div>
{{#if this.canAttachUploads}}
<ChatComposerUploads @fullPage={{this.fullPage}} @fileUploadElementId={{this.fileUploadElementId}} @onUploadChanged={{action "uploadsChanged"}} />
<ChatComposerUploads @fileUploadElementId={{this.fileUploadElementId}} @onUploadChanged={{action "uploadsChanged"}} />
{{/if}}
{{#unless this.chatChannel.isDraft}}

View File

@ -23,7 +23,6 @@
@chatChannel={{this.previewedChannel}}
@expanded={{true}}
@floatHidden={{false}}
@fullPage={{true}}
@includeHeader={{false}}
@onSwitchChannel={{action "onSwitchFromDraftChannel"}}
/>

View File

@ -1,4 +1,4 @@
{{#if (and this.fullPage this.includeHeader)}}
{{#if (and this.chatStateManager.isFullPage this.includeHeader)}}
<div
class="chat-full-page-header
{{unless this.chatChannel.isFollowing "-not-following"}}"
@ -6,17 +6,17 @@
<div class="chat-channel-header-details">
{{#if this.site.mobileView}}
<div class="chat-full-page-header__left-actions">
<DButton @class="btn-flat" @icon="chevron-left" @action={{this.onBackClick}} />
<DButton @class="chat-full-page-header__back-btn no-text btn-flat" @icon="chevron-left" @action={{this.onBackClick}} />
</div>
{{/if}}
<LinkTo @route={{this.infoTabRoute}} @models={{array this.chatChannel.id (slugify-channel this.chatChannel)}} class="chat-full-page-header__title">
<LinkTo @route={{this.infoTabRoute}} @models={{array this.chatChannel.id (slugify-channel this.chatChannel)}} class="chat-channel-title-wrapper">
<ChatChannelTitle @channel={{this.chatChannel}} />
</LinkTo>
{{#if this.showCloseFullScreenBtn}}
<div class="chat-full-page-header__right-actions">
<FlatButton @class="chat-full-screen-button" @icon="discourse-compress" @action={{action "onCloseFullScreen" this.chatChannel}} @title="chat.close_full_page" />
<DButton @icon="discourse-compress" @title="chat.close_full_page" class="open-drawer-btn btn-flat no-text" @action={{action "onCloseFullScreen"}} />
</div>
{{/if}}
</div>

View File

@ -1,6 +1,6 @@
<div class="chat-message-actions-container" data-id={{this.message.id}}>
<div class="chat-message-actions">
{{#if this.chatPreferredMode.isFullPage}}
{{#if this.chatStateManager.isFullPagePreferred}}
{{#each this.emojiReactions as |reaction|}}
<ChatMessageReaction @reaction={{reaction}} @react={{this.messageActions.react}} @class="show" />
{{/each}}

View File

@ -1,3 +1,3 @@
{{#if this.chat.activeChannel}}
<ChatLivePane @chatChannel={{this.chat.activeChannel}} @expanded={{true}} @floatHidden={{false}} @fullPage={{true}} @onBackClick={{action "navigateToIndex"}} @onSwitchChannel={{action "switchChannel"}} />
<ChatLivePane @chatChannel={{this.chat.activeChannel}} @expanded={{true}} @floatHidden={{false}} @onBackClick={{action "navigateToIndex"}} @onSwitchChannel={{action "switchChannel"}} />
{{/if}}

View File

@ -11,7 +11,9 @@
{{#if (and this.draftChannelView this.expanded)}}
<div class="topic-chat-drawer-header__left-actions">
<div class="topic-chat-drawer-header__top-line">
<FlatButton @class="topic-chat-drawer-header__return-to-channels-btn" @icon="chevron-left" @action={{action "fetchChannels"}} @title="chat.return_to_list" />
<LinkTo title={{i18n "chat.return_to_list"}} class="topic-chat-drawer-header__return-to-channels-btn" @route="chat">
{{d-icon "chevron-left"}}
</LinkTo>
</div>
</div>
@ -22,9 +24,9 @@
</span>
{{else if this.chatView}}
{{#if this.expanded}}
<div class="topic-chat-drawer-header__left-actions">
<FlatButton @class="topic-chat-drawer-header__return-to-channels-btn" @icon="chevron-left" @action={{action "fetchChannels"}} @title="chat.return_to_list" />
</div>
<LinkTo title={{i18n "chat.return_to_list"}} class="topic-chat-drawer-header__return-to-channels-btn" @route="chat">
{{d-icon "chevron-left"}}
</LinkTo>
{{/if}}
{{#if this.chat.activeChannel}}
@ -57,15 +59,7 @@
<div class="topic-chat-drawer-header__right-actions">
<div class="topic-chat-drawer-header__top-line {{this.topLineClass}}">
{{#if this.expanded}}
<button
class="btn-flat topic-chat-drawer-header__full-screen-btn"
onmouseup={{action "openInFullPage"}}
icon="discourse-expand"
title={{i18n "chat.open_full_page"}}
type="button"
>
{{d-icon "discourse-expand"}}
</button>
<DButton @icon="discourse-expand" class="btn-flat btn-link topic-chat-drawer-header__full-screen-btn" @title={{"chat.open_full_page"}} @action={{this.openInFullPage}} />
{{/if}}
<FlatButton @icon={{this.expandIcon}} @class="topic-chat-drawer-header__expand-btn" @action={{action "toggleExpand"}} @title="chat.collapse" />
@ -80,11 +74,11 @@
{{#if this.expanded}}
<div class="topic-chat-drawer-content">
{{#if (and this.chatView this.chat.activeChannel)}}
<ChatLivePane @chatChannel={{this.chat.activeChannel}} @expanded={{this.expanded}} @floatHidden={{this.hidden}} @fullPage={{false}} @onSwitchChannel={{action "switchChannel"}} />
<ChatLivePane @chatChannel={{this.chat.activeChannel}} @expanded={{this.expanded}} @floatHidden={{this.hidden}} @onSwitchChannel={{action "switchChannel"}} />
{{else if this.draftChannelView}}
<ChatDraftChannelScreen @onSwitchChannel={{action "switchChannel"}} />
{{else}}
<ChannelsList @floatHidden={{this.hidden}} @onOpenView={{action "openView"}} @onSelect={{action "switchChannel"}} />
<ChannelsList @floatHidden={{this.hidden}} @onOpenView={{action "openURL"}} @onSelect={{action "switchChannel"}} />
{{/if}}
</div>
{{/if}}

View File

@ -8,7 +8,7 @@ export default createWidget("header-chat-link", {
chat: null,
tagName: "li.header-dropdown-toggle.open-chat",
title: "chat.title",
services: ["chat", "router", "chatPreferredMode", "fullPageChat"],
services: ["chat", "router", "chatStateManager"],
html() {
if (!this.chat.userCanChat) {
@ -40,7 +40,7 @@ export default createWidget("header-chat-link", {
chatLinkHtml(indicatorNode) {
return h(
`a.icon${
this.fullPageChat.isActive || this.chat.chatOpen ? ".active" : ""
this.chatStateManager.isFullPage || this.chat.chatOpen ? ".active" : ""
}`,
{ attributes: { tabindex: 0 } },
[iconNode("comment"), indicatorNode].filter(Boolean)
@ -61,20 +61,13 @@ export default createWidget("header-chat-link", {
},
click() {
if (this.fullPageChat.isActive && !this.site.mobileView) {
if (this.chatStateManager.isFullPage && !this.site.mobileView) {
return;
}
if (
this.chat.sidebarActive ||
this.site.mobileView ||
this.chatPreferredMode.isFullPage
) {
this.chatPreferredMode.setFullPage();
return this.router.transitionTo("chat");
} else {
this.appEvents.trigger("chat:toggle-open");
}
return this.router.transitionTo(
this.chatStateManager.lastKnownChatURL || "chat"
);
},
chatRerenderHeader() {

View File

@ -1,22 +0,0 @@
import hbs from "discourse/widgets/hbs-compiler";
import { createWidget } from "discourse/widgets/widget";
import ChatChannel from "discourse/plugins/chat/discourse/models/chat-channel";
export default createWidget("topic-chat-button", {
tagName: "button.btn.btn-default.topic-chat-button",
title: "chat.open",
click() {
this.appEvents.trigger(
"chat:open-channel-for-chatable",
ChatChannel.create(this.attrs.chat_channel)
);
},
template: hbs`
{{d-icon "far-comments"}}
<span class="label">
{{i18n "chat.topic_button_title"}}
</span>
`,
});

View File

@ -10,9 +10,13 @@
&__header {
display: flex;
gap: 1rem;
align-items: center;
margin: 1rem 0 1rem 1rem;
justify-content: flex-start;
margin-bottom: 1em;
.new-channel-btn {
margin-left: auto;
}
}
&__title {
@ -29,10 +33,6 @@
}
}
.new-channel-btn {
margin-left: auto;
}
&__cards {
display: grid;
grid-template-columns: repeat(2, 1fr);

View File

@ -2,11 +2,6 @@
display: flex;
flex-direction: column;
height: 100%;
&__back-btn {
font-size: var(--font-down-1);
margin: 0 0 1rem 0;
}
}
// Info header
@ -18,11 +13,6 @@
box-sizing: border-box;
}
.channel-info__back-btn {
margin-bottom: 1rem;
display: block;
}
.channel-info-header__title {
font-size: var(--font-up-2);
margin: 0;

View File

@ -1,3 +1,8 @@
.chat-channel-title-wrapper {
display: flex;
align-items: center;
}
.chat-channel-title {
display: flex;
align-items: center;

View File

@ -91,6 +91,7 @@ body.composer-open .topic-chat-float-container {
.topic-chat-drawer-header__right-actions {
display: flex;
height: 100%;
margin-left: auto;
}
.topic-chat-drawer-header__top-line {
@ -172,13 +173,27 @@ body.composer-open .topic-chat-float-container {
}
}
&__return-to-channels-btn,
&__close-btn,
&__return-to-channels-btn,
&__full-screen-btn,
&__expand-btn {
height: 100%;
max-height: 2.5rem;
width: 2.5rem;
height: 100%;
min-width: 40px;
width: 40px;
display: flex;
justify-content: center;
align-items: center;
.d-icon {
color: var(--primary-low-mid);
}
&:visited {
.d-icon {
color: var(--primary-low-mid);
}
}
&:focus {
outline: none;

View File

@ -149,8 +149,8 @@ $float-height: 530px;
}
}
.edit-channel-membership-btn,
.new-dm,
.open-browse-page-btn,
.open-draft-channel-page-btn,
.chat-channel-leave-btn {
background: transparent;
color: var(--primary-medium);
@ -202,7 +202,7 @@ $float-height: 530px;
}
}
}
.edit-channel-membership-btn {
.open-browse-page-btn {
&:hover {
background: none;
}
@ -318,6 +318,22 @@ $float-height: 530px;
min-height: 1px;
position: relative;
.open-drawer-btn {
color: var(--primary-low-mid);
&:visited {
color: var(--primary-low-mid);
}
&:hover {
color: var(--primary);
}
> * {
pointer-events: none;
}
}
.chat-messages-scroll {
flex-grow: 1;
overflow-y: scroll;
@ -419,6 +435,10 @@ $float-height: 530px;
transition: opacity 50ms ease-in;
opacity: 1;
.chat-user-avatar {
pointer-events: none;
}
.chat-channel-unread-indicator {
margin-left: 0.5rem;
}
@ -629,6 +649,16 @@ body.has-full-page-chat {
border-bottom: 1px solid var(--primary-low);
background: var(--secondary);
z-index: 3;
display: flex;
align-items: center;
&__back-btn {
width: 40px;
min-width: 40px;
display: flex;
align-items: center;
justify-content: center;
}
.chat-channel-title {
.category-chat-name,
@ -680,9 +710,12 @@ body.has-full-page-chat {
}
.chat-full-page-header {
box-sizing: border-box;
.chat-channel-header-details {
display: flex;
align-items: stretch;
flex: 1;
.chat-channel-archive-status {
text-align: right;

View File

@ -178,11 +178,11 @@
.no-results {
text-align: center;
padding: 1rem;
position: absolute;
width: 100%;
box-shadow: shadow("card");
background: var(--secondary);
margin: 0;
box-sizing: border-box;
}
.fetching-preview-message {

View File

@ -1,3 +1,12 @@
.chat-channel-title-wrapper {
padding: 0.25rem;
&:hover {
background: var(--primary-very-low);
border-radius: 5px;
}
}
.channels-list {
.chat-channel-title {
max-width: 100%;

View File

@ -18,7 +18,9 @@
}
.chat-full-page-header {
padding: 1rem;
padding: 0 1rem;
height: 65px;
min-height: 65px;
flex-shrink: 0;
}

View File

@ -1,5 +0,0 @@
.channel-info {
&__back-btn {
margin: 0.5rem 0 1rem 0;
}
}

View File

@ -92,7 +92,7 @@
}
}
.btn-floating.new-dm {
.btn-floating.open-draft-channel-page-btn {
position: absolute;
background: var(--tertiary);
bottom: 2.5rem;

View File

@ -43,6 +43,15 @@ body.has-full-page-chat {
overflow-x: hidden;
width: 100%;
.btn:active,
.btn:hover {
background: var(--secondary-very-high);
.d-icon {
color: var(--primary-medium);
}
}
.chat-live-pane {
border-radius: 0;
padding: 0;
@ -54,7 +63,9 @@ body.has-full-page-chat {
.chat-full-page-header {
background-color: var(--secondary);
padding: 0.5em 10px;
padding: 0 10px;
height: 50px;
min-height: 50px;
}
.chat-messages-scroll {

View File

@ -77,8 +77,8 @@
}
}
.new-dm,
.edit-channel-membership-btn,
.open-draft-channel-page-btn,
.open-browse-page-btn,
.edit-channels-dropdown .select-kit-header,
.chat-channel-leave-btn {
display: flex;

View File

@ -375,8 +375,6 @@ en:
public: "Channel history is retained for %{days} days."
dm: "Personal chat history is retained for %{days} days."
topic_button_title: "Chat"
flags:
off_topic: "This message is not relevant to the current discussion as defined by the channel title, and should probably be moved elsewhere."
inappropriate: "This message contains content that a reasonable person would consider offensive, abusive, or a violation of <a href=\"%{basePath}/guidelines\">our community guidelines</a>."

View File

@ -20,7 +20,6 @@ register_asset "stylesheets/common/chat-drawer.scss"
register_asset "stylesheets/mobile/chat-index.scss", :mobile
register_asset "stylesheets/common/chat-channel-preview-card.scss"
register_asset "stylesheets/common/chat-channel-info.scss"
register_asset "stylesheets/mobile/chat-channel-info.scss", :mobile
register_asset "stylesheets/common/chat-draft-channel.scss"
register_asset "stylesheets/common/chat-tabs.scss"
register_asset "stylesheets/common/chat-form.scss"

View File

@ -6,9 +6,11 @@ RSpec.describe "Navigation", type: :system, js: true do
fab!(:post) { Fabricate(:post, topic: topic) }
fab!(:user) { Fabricate(:admin) }
fab!(:category_channel) { Fabricate(:category_channel) }
fab!(:category_channel_2) { Fabricate(:category_channel) }
fab!(:message) { Fabricate(:chat_message, chat_channel: category_channel) }
let(:chat_page) { PageObjects::Pages::Chat.new }
let(:sidebar_page) { PageObjects::Pages::Sidebar.new }
let(:chat_drawer_page) { PageObjects::Pages::ChatDrawer.new }
before do
# ensures we have one valid registered admin
@ -17,13 +19,14 @@ RSpec.describe "Navigation", type: :system, js: true do
SiteSetting.chat_enabled = true
SiteSetting.chat_allowed_groups = Group::AUTO_GROUPS[:everyone]
category_channel.add(user)
category_channel_2.add(user)
sign_in(user)
end
context "when visiting /chat" do
it "opens full page" do
chat_page.open_full_page
chat_page.open
expect(page).to have_current_path(
chat.channel_path(category_channel.id, category_channel.slug),
@ -46,7 +49,7 @@ RSpec.describe "Navigation", type: :system, js: true do
it "opens the full page" do
visit("/")
chat_page.open_from_header
chat_page.maximize_drawer
chat_drawer_page.maximize
expect(page).to have_current_path(
chat.channel_path(category_channel.id, category_channel.slug),
@ -63,7 +66,7 @@ RSpec.describe "Navigation", type: :system, js: true do
context "when opening chat with drawer as preferred mode" do
it "opens the full page" do
chat_page.open_full_page
chat_page.open
chat_page.minimize_full_page
expect(page).to have_css(".topic-chat-container.expanded.visible")
@ -77,7 +80,7 @@ RSpec.describe "Navigation", type: :system, js: true do
context "when collapsing full page with no previous state" do
it "redirects to home page" do
chat_page.open_full_page
chat_page.open
chat_page.minimize_full_page
expect(page).to have_current_path(latest_path)
@ -88,7 +91,7 @@ RSpec.describe "Navigation", type: :system, js: true do
it "redirects to previous state" do
visit("/t/-/#{topic.id}")
chat_page.open_from_header
chat_page.maximize_drawer
chat_drawer_page.maximize
chat_page.minimize_full_page
expect(page).to have_current_path("/t/#{topic.slug}/#{topic.id}")
@ -106,7 +109,7 @@ RSpec.describe "Navigation", type: :system, js: true do
it "opens channel in drawer" do
visit("/t/-/#{topic.id}")
chat_page.open_from_header
chat_page.close_drawer
chat_drawer_page.close
find("a[title='#{category_channel.title}']").click
expect(page).to have_css(".chat-message-container[data-id='#{message.id}']")
@ -117,7 +120,7 @@ RSpec.describe "Navigation", type: :system, js: true do
it "opens channel in full page" do
visit("/")
chat_page.open_from_header
chat_page.maximize_drawer
chat_drawer_page.maximize
visit("/")
find("a[title='#{category_channel.title}']").click
@ -130,10 +133,21 @@ RSpec.describe "Navigation", type: :system, js: true do
context "when starting draft from sidebar with drawer preferred" do
it "opens draft in drawer" do
visit("/")
sidebar_page.start_draft_dm
sidebar_page.open_draft_channel
expect(page).to have_current_path("/")
expect(page).to have_css(".topic-chat-container.expanded.visible")
expect(page).to have_css(".topic-chat-container.expanded.visible .direct-message-creator")
end
end
context "when starting draft from drawer with drawer preferred" do
it "opens draft in drawer" do
visit("/")
chat_page.open_from_header
chat_drawer_page.open_draft_channel
expect(page).to have_current_path("/")
expect(page).to have_css(".topic-chat-container.expanded.visible .direct-message-creator")
end
end
@ -141,13 +155,66 @@ RSpec.describe "Navigation", type: :system, js: true do
it "opens draft in full page" do
visit("/")
chat_page.open_from_header
chat_page.maximize_drawer
chat_drawer_page.maximize
visit("/")
sidebar_page.start_draft_dm
sidebar_page.open_draft_channel
expect(page).to have_current_path("/chat/draft-channel")
expect(page).not_to have_css(".topic-chat-container.expanded.visible")
end
end
context "when opening browse page from drawer in drawer mode" do
it "opens browser page in full page" do
visit("/")
chat_page.open_from_header
chat_drawer_page.open_browse
expect(page).to have_current_path("/chat/browse/open")
expect(page).not_to have_css(".topic-chat-container.expanded.visible")
end
end
context "when opening browse page from sidebar in drawer mode" do
it "opens browser page in full page" do
visit("/")
chat_page.open_from_header
sidebar_page.open_browse
expect(page).to have_current_path("/chat/browse/open")
expect(page).not_to have_css(".topic-chat-container.expanded.visible")
end
end
context "when re-opening drawer after navigating to a channel" do
it "opens drawer on correct channel" do
visit("/")
chat_page.open_from_header
chat_drawer_page.open_channel(category_channel_2)
chat_drawer_page.open_index
chat_drawer_page.close
chat_page.open_from_header
expect(page).to have_current_path("/")
expect(page).to have_css(".topic-chat-container.expanded.visible")
expect(page).to have_content(category_channel_2.title)
end
end
context "when re-opening full page chat after navigating to a channel" do
it "opens full page chat on correct channel" do
visit("/")
chat_page.open_from_header
chat_drawer_page.maximize
sidebar_page.open_channel(category_channel_2)
find("#site-logo").click
chat_page.open_from_header
expect(page).to have_current_path(
chat.channel_path(category_channel_2.id, category_channel_2.slug),
)
expect(page).to have_content(category_channel_2.title)
end
end
end
end

View File

@ -7,20 +7,12 @@ module PageObjects
find(".open-chat").click
end
def open_full_page
def open
visit("/chat")
end
def maximize_drawer
find(".topic-chat-drawer-header__full-screen-btn").click
end
def close_drawer
find(".topic-chat-drawer-header__close-btn").click
end
def minimize_full_page
find(".chat-full-screen-button").click
find(".open-drawer-btn").click
end
end
end

View File

@ -0,0 +1,34 @@
# frozen_string_literal: true
module PageObjects
module Pages
class ChatDrawer < PageObjects::Pages::Base
VISIBLE_DRAWER = ".topic-chat-container.expanded.visible"
def open_browse
find("#{VISIBLE_DRAWER} .open-browse-page-btn").click
end
def open_draft_channel
find("#{VISIBLE_DRAWER} .open-draft-channel-page-btn").click
end
def close
find("#{VISIBLE_DRAWER} .topic-chat-drawer-header__close-btn").click
end
def open_index
find("#{VISIBLE_DRAWER} .topic-chat-drawer-header__return-to-channels-btn").click
end
def open_channel(channel)
find(
"#{VISIBLE_DRAWER} .channels-list .chat-channel-row[data-chat-channel-id='#{channel.id}']",
).click
end
def maximize
find("#{VISIBLE_DRAWER} .topic-chat-drawer-header__full-screen-btn").click
end
end
end
end

View File

@ -3,9 +3,17 @@
module PageObjects
module Pages
class Sidebar < PageObjects::Pages::Base
def start_draft_dm
def open_draft_channel
find(".sidebar-section-chat-dms .sidebar-section-header-button", visible: false).click
end
def open_browse
find(".sidebar-section-chat-channels .sidebar-section-header-button", visible: false).click
end
def open_channel(channel)
find(".sidebar-section-link[href='/chat/channel/#{channel.id}/#{channel.slug}']").click
end
end
end
end

View File

@ -136,7 +136,6 @@ acceptance("Discourse Chat - Composer - unreliable network", function (needs) {
});
test("Sending a message with unreliable network", async function (assert) {
this.chatService.set("chatWindowFullPage", false);
await visit("/chat/channel/11/-");
await fillIn(".chat-composer-input", "network-error-message");
await click(".send-btn");
@ -174,7 +173,6 @@ acceptance("Discourse Chat - Composer - unreliable network", function (needs) {
});
test("Draft with unreliable network", async function (assert) {
this.chatService.set("chatWindowFullPage", false);
await visit("/chat/channel/11/-");
this.chatService.set("isNetworkUnreliable", true);
await settled();

View File

@ -165,9 +165,10 @@ acceptance("Discourse Chat - Keyboard shortcuts", function (needs) {
test("switching channel with alt+arrow keys in float", async function (assert) {
await visit("/latest");
this.chatService.set("sidebarActive", false);
this.chatService.set("chatWindowFullPage", false);
await click(".header-dropdown-toggle.open-chat");
await click("#chat-channel-row-4");
assert.ok(visible(".topic-chat-float-container"), "chat float is open");
assert.ok(query(".topic-chat-container").classList.contains("channel-4"));
@ -184,9 +185,10 @@ acceptance("Discourse Chat - Keyboard shortcuts", function (needs) {
});
test("simple composer formatting shortcuts", async function (assert) {
await visit("/latest");
this.chatService.set("sidebarActive", false);
await visit("/latest");
await click(".header-dropdown-toggle.open-chat");
await click(".chat-channel-row");
const composerInput = query(".chat-composer-input");
await fillIn(composerInput, "test text");
@ -230,6 +232,7 @@ acceptance("Discourse Chat - Keyboard shortcuts", function (needs) {
this.chatService.set("sidebarActive", false);
await click(".header-dropdown-toggle.open-chat");
await click(".chat-channel-row");
await fillIn(".chat-composer-input", stagedMessageText);
await click(".chat-composer-inline-button");
await triggerKeyEvent(".chat-composer-input", "keydown", "ArrowUp");
@ -245,6 +248,7 @@ acceptance("Discourse Chat - Keyboard shortcuts", function (needs) {
this.chatService.set("sidebarActive", false);
await click(".header-dropdown-toggle.open-chat");
await click(".chat-channel-row");
await focus(".chat-composer-input");
await fillIn(".chat-composer-input", "This is a link to ");
@ -275,17 +279,16 @@ acceptance("Discourse Chat - Keyboard shortcuts", function (needs) {
test("Dash key (-) opens chat float", async function (assert) {
await visit("/latest");
this.chatService.set("sidebarActive", false);
this.chatService.set("chatWindowFullPage", false);
await triggerKeyEvent(document.body, "keydown", "-");
assert.ok(exists(".topic-chat-drawer-content"), "chat float is open");
});
test("Pressing Escape when drawer is opened", async function (assert) {
await visit("/latest");
this.chatService.set("sidebarActive", false);
this.chatService.set("chatWindowFullPage", false);
await visit("/latest");
await click(".header-dropdown-toggle.open-chat");
await click(".chat-channel-row");
const composerInput = query(".chat-composer-input");
await focus(composerInput);
@ -299,7 +302,6 @@ acceptance("Discourse Chat - Keyboard shortcuts", function (needs) {
test("Pressing Escape when full page is opened", async function (assert) {
this.chatService.set("sidebarActive", false);
this.chatService.set("chatWindowFullPage", true);
await visit("/chat/channel/75/@hawk");
const composerInput = query(".chat-composer-input");
await focus(composerInput);

View File

@ -141,7 +141,6 @@ acceptance("Discourse Chat - without unread", function (needs) {
// TODO: needs a future change to how we handle URLS to be possible
skip("Clicking mention notification from outside chat opens the float", async function (assert) {
this.chatService.set("chatWindowFullPage", false);
await visit("/t/internationalization-localization/280");
await click(".header-dropdown-toggle.current-user");
await click("#quick-access-notifications .chat-mention");
@ -226,9 +225,9 @@ acceptance("Discourse Chat - without unread", function (needs) {
"it doesnt show the rebake button for non staff"
);
await visit("/");
updateCurrentUser({ admin: true, moderator: true });
await visit("/chat/channel/11/another-category");
await visit("/chat");
await triggerEvent(".chat-message-container[data-id='174']", "mouseenter");
await currentUserDropdown.expand();
@ -368,9 +367,10 @@ acceptance("Discourse Chat - without unread", function (needs) {
test("Reply-to is stored in draft", async function (assert) {
this.chatService.set("sidebarActive", false);
this.chatService.set("chatWindowFullPage", false);
await visit("/latest");
this.appEvents.trigger("chat:toggle-open");
await click(".header-dropdown-toggle.open-chat");
await click(".chat-channel-row");
await settled();
await click(".topic-chat-drawer-header__return-to-channels-btn");
@ -708,7 +708,7 @@ Widget.triangulate(arg: "test")
test("creating a new direct message channel works", async function (assert) {
await visit("/chat/channel/11/another-category");
await click(".new-dm");
await click(".open-draft-channel-page-btn");
await fillIn(".filter-usernames", "hawk");
await click("li.user[data-username='hawk']");
@ -726,7 +726,7 @@ Widget.triangulate(arg: "test")
test("creating a new direct message channel from popup chat works", async function (assert) {
await visit("/t/internationalization-localization/280");
await click(".new-dm");
await click(".open-draft-channel-page-btn");
await fillIn(".filter-usernames", "hawk");
await click('.chat-user-avatar-container[data-user-card="hawk"]');
assert.ok(query(".selected-user").innerText, "hawk");
@ -979,33 +979,12 @@ acceptance(
test("Expand button takes you to full page chat on the correct channel", async function (assert) {
await visit("/t/internationalization-localization/280");
this.chatService.set("sidebarActive", false);
await visit(".header-dropdown-toggle.open-chat");
await click(".header-dropdown-toggle.open-chat");
await click(".topic-chat-drawer-header__full-screen-btn");
assert.equal(currentURL(), `/chat/channel/11/another-category`);
});
test("Chat opens to full-page channel with unread messages when sidebar is installed", async function (assert) {
await visit("/t/internationalization-localization/280");
this.chatService.set("sidebarActive", true);
await click(".header-dropdown-toggle.open-chat");
assert.equal(currentURL(), `/chat/channel/11/another-category`);
assert.notOk(
visible(".topic-chat-float-container"),
"chat float is not open"
);
});
test("Chat float opens on header icon click when sidebar is not installed", async function (assert) {
await visit("/t/internationalization-localization/280");
this.chatService.set("sidebarActive", false);
this.chatService.set("chatWindowFullPage", false);
await click(".header-dropdown-toggle.open-chat");
assert.ok(visible(".topic-chat-float-container"), "chat float is open");
});
test("Unread header indicator is present", async function (assert) {
await visit("/t/internationalization-localization/280");
@ -1047,7 +1026,7 @@ acceptance(
test("Close fullscreen chat button present", async function (assert) {
await visit("/chat/channel/11/another-category");
assert.ok(exists(".chat-full-screen-button"));
assert.ok(exists(".open-drawer-btn"));
});
}
);
@ -1110,6 +1089,7 @@ acceptance(
visible(".topic-chat-drawer-header__top-line--expanded"),
"chat float is expanded"
);
await click("#chat-channel-row-9");
await click(".topic-chat-drawer-header__title");
assert.equal(currentURL(), `/chat/channel/9/site/info/members`);
});
@ -1118,16 +1098,22 @@ acceptance(
await visit("/t/internationalization-localization/280");
this.chatService.set("sidebarActive", false);
await click(".header-dropdown-toggle.open-chat");
await click(".chat-channel-row");
assert.ok(
visible(".topic-chat-drawer-header__top-line--expanded"),
"chat float is expanded"
);
await click(".topic-chat-drawer-header__expand-btn");
assert.ok(
visible(".topic-chat-drawer-header__top-line--collapsed"),
"chat float is collapsed"
);
await click(".topic-chat-drawer-header__title");
assert.ok(
visible(".topic-chat-drawer-header__top-line--expanded"),
"chat float is expanded"
@ -1181,14 +1167,16 @@ acceptance(
test("Chat float open to DM channel with unread messages with sidebar off", async function (assert) {
await visit("/t/internationalization-localization/280");
this.chatService.set("sidebarActive", false);
this.chatService.set("chatWindowFullPage", false);
await click(".header-dropdown-toggle.open-chat");
await click("#chat-channel-row-75");
const chatContainer = query(".topic-chat-container");
assert.ok(chatContainer.classList.contains("channel-75"));
});
test("Chat full page open to DM channel with unread messages with sidebar on", async function (assert) {
this.chatService.set("sidebarActive", true);
this.owner.lookup("service:chat-state-manager").prefersFullPage();
await visit("/t/internationalization-localization/280");
await click(".header-dropdown-toggle.open-chat");
@ -1248,8 +1236,6 @@ acceptance(
});
test("Create channel modal", async function (assert) {
this.container.lookup("service:chat").set("chatWindowFullPage", true);
await visit("/chat/browse");
await click(".new-channel-btn");
@ -1415,7 +1401,6 @@ acceptance("Discourse Chat - image uploads", function (needs) {
test("uploading files in chat works", async function (assert) {
await visit("/t/internationalization-localization/280");
this.container.lookup("service:chat").set("sidebarActive", false);
this.container.lookup("service:chat").set("chatWindowFullPage", false);
await click(".header-dropdown-toggle.open-chat");
assert.ok(visible(".topic-chat-float-container"), "chat float is open");
@ -1475,8 +1460,8 @@ acceptance("Discourse Chat - image uploads", function (needs) {
assert.ok(exists(".d-editor-input"), "the composer input is visible");
this.container.lookup("service:chat").set("sidebarActive", false);
this.container.lookup("service:chat").set("chatWindowFullPage", false);
await click(".header-dropdown-toggle.open-chat");
await click(".chat-channel-row");
assert.ok(visible(".topic-chat-float-container"), "chat float is open");
const appEvents = loggedInUser().appEvents;
@ -1816,12 +1801,12 @@ acceptance("Discourse Chat - Direct Message Creator", function (needs) {
test("Create a direct message", async function (assert) {
await visit("/latest");
await click(".header-dropdown-toggle.open-chat");
await click(".topic-chat-drawer-header__return-to-channels-btn");
assert.ok(
!exists(".new-dm.btn-floating"),
!exists(".open-draft-channel-page-btn.btn-floating"),
"mobile floating button should not exist on desktop"
);
await click(".btn.new-dm");
await click(".btn.open-draft-channel-page-btn");
assert.ok(exists(".chat-draft"), "view changes to draft channel screen");
});
});
@ -1841,8 +1826,6 @@ acceptance("Discourse Chat - Drawer", function (needs) {
});
test("Position after closing reduced composer", async function (assert) {
this.chatService.set("chatWindowFullPage", false);
await visit("/t/internationalization-localization/280");
await click(".btn.create");
await click(".toggle-preview");

View File

@ -40,12 +40,13 @@ acceptance("Discourse Chat - Mobile test", function (needs) {
assert.equal(currentURL(), "/chat");
assert.ok(exists(".channels-list"));
await click(".chat-channel-row.chat-channel-7");
assert.notOk(exists(".chat-full-screen-button"));
assert.notOk(exists(".open-drawer-btn"));
});
test("Chat new personal chat buttons", async function (assert) {
await visit("/chat");
await click(".new-dm.btn-floating");
await click(".open-draft-channel-page-btn.btn-floating");
assert.strictEqual(
currentURL(),
"/chat/draft-channel",
@ -53,6 +54,7 @@ acceptance("Discourse Chat - Mobile test", function (needs) {
);
await click(".chat-draft-header__btn");
assert.strictEqual(
currentURL(),
"/chat",
@ -62,7 +64,8 @@ acceptance("Discourse Chat - Mobile test", function (needs) {
test("Chat browse screen back button", async function (assert) {
await visit("/chat/browse");
await click(".chat-browse-view__back");
await click(".chat-full-page-header__back-btn");
assert.strictEqual(
currentURL(),
"/chat",

View File

@ -1,39 +0,0 @@
import {
acceptance,
loggedInUser,
} from "discourse/tests/helpers/qunit-helpers";
import { click, currentURL, visit } from "@ember/test-helpers";
import { generateChatView } from "discourse/plugins/chat/chat-fixtures";
import { test } from "qunit";
import fabricators from "../helpers/fabricators";
acceptance("Discourse Chat - Navigation scenarios", function (needs) {
needs.user({ can_chat: true, has_chat_enabled: true });
needs.settings({ chat_enabled: true });
needs.pretender((server, helper) => {
server.get("/chat/chat_channels.json", () =>
helper.response({ public_channels: [fabricators.chatChannel()] })
);
server.get("/chat/:chat_channel_id/messages.json", () =>
helper.response(generateChatView(loggedInUser()))
);
});
test("Switching off full screen brings you back to previous route", async function (assert) {
this.container.lookup("service:full-page-chat").exit();
await visit("/t/-/280");
await visit("/chat");
assert.equal(currentURL(), "/chat/channel/1/my-category-title");
await click(".chat-full-screen-button");
assert.ok(
currentURL().startsWith("/t/internationalization-localization/280"),
"it redirects back to the visited topic before going full screen"
);
});
});

View File

@ -7,7 +7,7 @@ import {
query,
visible,
} from "discourse/tests/helpers/qunit-helpers";
import { click, settled, visit } from "@ember/test-helpers";
import { click, visit } from "@ember/test-helpers";
import {
chatChannels,
directMessageChannels,
@ -83,17 +83,15 @@ acceptance("Discourse Chat - User card test", function (needs) {
test("user card has chat button that opens the correct channel", async function (assert) {
this.chatService.set("sidebarActive", false);
this.chatService.set("chatWindowFullPage", false);
await visit("/latest");
this.appEvents.trigger("chat:toggle-open");
await settled();
await click(".topic-chat-drawer-header__return-to-channels-btn");
await visit("/");
await click(".header-dropdown-toggle.open-chat");
await click(".chat-channel-row.chat-channel-9");
await click("[data-user-card='hawk']");
assert.ok(exists(".user-card-chat-btn"));
await click(".user-card-chat-btn");
assert.ok(visible(".topic-chat-float-container"), "chat float is open");
assert.ok(query(".topic-chat-container").classList.contains("channel-75"));
});

View File

@ -3,7 +3,6 @@ import componentTest, {
} from "discourse/tests/helpers/component-test";
import { exists } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
import { click, triggerKeyEvent } from "@ember/test-helpers";
import fabricators from "../helpers/fabricators";
import { module } from "qunit";
@ -39,42 +38,6 @@ module("Discourse Chat | Component | chat-channel-row", function (hooks) {
},
});
componentTest("receives click", {
template: hbs`{{chat-channel-row switchChannel=switchChannel channel=channel}}`,
beforeEach() {
this.set("switchedChannel", null);
this.set("channel", fabricators.chatChannel());
this.set("switchChannel", (channel) =>
this.set("switchedChannel", channel.id)
);
},
async test(assert) {
await click(".chat-channel-row");
assert.strictEqual(this.switchedChannel, this.channel.id);
},
});
componentTest("receives Enter keyup", {
template: hbs`{{chat-channel-row switchChannel=switchChannel channel=channel}}`,
beforeEach() {
this.set("switchedChannel", null);
this.set("channel", fabricators.chatChannel());
this.set("switchChannel", (channel) =>
this.set("switchedChannel", channel.id)
);
},
async test(assert) {
await triggerKeyEvent(".chat-channel-row", "keyup", "Enter");
assert.strictEqual(this.switchedChannel, this.channel.id);
},
});
componentTest(
"a row is active when the associated channel is active and visible",
{

View File

@ -1,13 +1,11 @@
import componentTest, {
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import { exists } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
import fabricators from "../helpers/fabricators";
import selectKit from "discourse/tests/helpers/select-kit-helper";
import pretender from "discourse/tests/helpers/create-pretender";
import { CHATABLE_TYPES } from "discourse/plugins/chat/discourse/models/chat-channel";
import { set } from "@ember/object";
import { module } from "qunit";
function membershipFixture(id, options = {}) {
@ -221,50 +219,3 @@ module(
});
}
);
module(
"Discourse Chat | Component | chat-channel-settings-view | Public channel - admin user",
function (hooks) {
setupRenderingTest(hooks);
componentTest("admin actions", {
template: hbs`{{chat-channel-settings-view channel=channel}}`,
beforeEach() {
set(this.currentUser, "admin", true);
set(this.currentUser, "has_chat_enabled", true);
this.siteSettings.chat_enabled = true;
this.set("channel", fabricators.chatChannel());
},
async test(assert) {
assert.ok(exists(".close-btn"));
assert.ok(exists(".delete-btn"));
},
});
}
);
module(
"Discourse Chat | Component | chat-channel-settings-view | Archived Public channel - admin user",
function (hooks) {
setupRenderingTest(hooks);
componentTest("archive action", {
template: hbs`{{chat-channel-settings-view channel=channel}}`,
beforeEach() {
set(this.currentUser, "admin", true);
set(this.currentUser, "has_chat_enabled", true);
this.siteSettings.chat_enabled = true;
this.siteSettings.chat_allow_archiving_channels = true;
this.set("channel", fabricators.chatChannel());
},
async test(assert) {
assert.ok(exists(".archive-btn"));
},
});
}
);

View File

@ -55,7 +55,6 @@ module("Discourse Chat | Component | chat-message", function (hooks) {
onStartSelectingMessages: () => {},
onSelectMessage: () => {},
bulkSelectMessages: () => {},
fullPage: false,
afterReactionAdded: () => {},
onHoverMessage: () => {},
};
@ -73,7 +72,6 @@ module("Discourse Chat | Component | chat-message", function (hooks) {
onStartSelectingMessages=onStartSelectingMessages
onSelectMessage=onSelectMessage
bulkSelectMessages=bulkSelectMessages
fullPage=fullPage
onHoverMessage=onHoverMessage
afterReactionAdded=reStickScrollIfNeeded
}}`;

View File

@ -1,38 +0,0 @@
import { module, test } from "qunit";
import { getOwner } from "discourse-common/lib/get-owner";
import Site from "discourse/models/site";
module(
"Discourse Chat | Unit | Service | chat-preferred-mode",
function (hooks) {
hooks.beforeEach(function () {
Site.currentProp("mobileView", false);
this.chatPreferredMode = getOwner(this).lookup(
"service:chat-preferred-mode"
);
});
test("defaults", function (assert) {
assert.strictEqual(this.chatPreferredMode.isDrawer, true);
assert.strictEqual(this.chatPreferredMode.isFullPage, false);
Site.currentProp("mobileView", true);
assert.strictEqual(this.chatPreferredMode.isDrawer, false);
assert.strictEqual(this.chatPreferredMode.isFullPage, true);
});
test("setFullPage", function (assert) {
this.chatPreferredMode.setFullPage();
assert.strictEqual(this.chatPreferredMode.isFullPage, true);
assert.strictEqual(this.chatPreferredMode.isDrawer, false);
});
test("setDrawer", function (assert) {
this.chatPreferredMode.setDrawer();
assert.strictEqual(this.chatPreferredMode.isFullPage, false);
assert.strictEqual(this.chatPreferredMode.isDrawer, true);
});
}
);

View File

@ -0,0 +1,82 @@
import { module, test } from "qunit";
import { setupTest } from "ember-qunit";
import Site from "discourse/models/site";
import sinon from "sinon";
module(
"Discourse Chat | Unit | Service | chat-state-manager",
function (hooks) {
setupTest(hooks);
hooks.beforeEach(function () {
this.subject = this.owner.lookup("service:chat-state-manager");
});
hooks.afterEach(function () {
this.subject.reset();
});
test("isFullPagePreferred", function (assert) {
assert.notOk(this.subject.isFullPagePreferred);
this.subject.prefersFullPage();
assert.ok(this.subject.isFullPagePreferred);
this.subject.prefersDrawer();
assert.notOk(this.subject.isFullPagePreferred);
this.subject.prefersDrawer();
Site.currentProp("mobileView", true);
assert.ok(this.subject.isFullPagePreferred);
});
test("isDrawerPreferred", function (assert) {
assert.ok(this.subject.isDrawerPreferred);
this.subject.prefersFullPage();
assert.notOk(this.subject.isDrawerPreferred);
this.subject.prefersDrawer();
assert.ok(this.subject.isDrawerPreferred);
});
test("lastKnownChatURL", function (assert) {
assert.strictEqual(this.subject.lastKnownChatURL, "/chat");
sinon.stub(this.subject.router, "currentURL").value("/foo");
this.subject.storeChatURL();
assert.strictEqual(this.subject.lastKnownChatURL, "/foo");
this.subject.storeChatURL("/bar");
assert.strictEqual(this.subject.lastKnownChatURL, "/bar");
});
test("lastKnownAppURL", function (assert) {
assert.strictEqual(this.subject.lastKnownAppURL, "/latest");
sinon.stub(this.subject.router, "currentURL").value("/foo");
this.subject.storeAppURL();
assert.strictEqual(this.subject.lastKnownAppURL, "/foo");
this.subject.storeAppURL("/bar");
assert.strictEqual(this.subject.lastKnownAppURL, "/bar");
});
test("isFullPage", function (assert) {
sinon.stub(this.subject.router, "currentRouteName").value("foo");
assert.notOk(this.subject.isFullPage);
sinon.stub(this.subject.router, "currentRouteName").value("chat");
assert.ok(this.subject.isFullPage);
});
}
);

View File

@ -1,40 +0,0 @@
import { module, test } from "qunit";
import { setupTest } from "ember-qunit";
module("Discourse Chat | Unit | Service | full-page-chat", function (hooks) {
setupTest(hooks);
hooks.beforeEach(function () {
this.fullPageChat = this.owner.lookup("service:full-page-chat");
});
hooks.afterEach(function () {
this.fullPageChat.exit();
});
test("defaults", function (assert) {
assert.strictEqual(this.fullPageChat.isActive, false);
});
test("enter", function (assert) {
this.fullPageChat.enter();
assert.strictEqual(this.fullPageChat.isActive, true);
});
test("exit", function (assert) {
this.fullPageChat.enter();
assert.strictEqual(this.fullPageChat.isActive, true);
this.fullPageChat.exit();
assert.strictEqual(this.fullPageChat.isActive, false);
});
test("previous route", function (assert) {
const name = "foo";
const params = { id: 1, slug: "bar" };
this.fullPageChat.enter({ name, params });
const routeInfo = this.fullPageChat.exit();
assert.strictEqual(routeInfo.name, name);
assert.deepEqual(routeInfo.params, params);
});
});