FEATURE: Add messages section links to experimental sidebar. (#17096)

This commit is contained in:
Alan Guo Xiang Tan 2022-06-16 13:33:40 +08:00 committed by GitHub
parent 888f50543d
commit c625dc0adc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 592 additions and 30 deletions

View File

@ -1,10 +1,96 @@
import { action } from "@ember/object";
import { cached } from "@glimmer/tracking";
import GlimmerComponent from "discourse/components/glimmer";
import Composer from "discourse/models/composer";
import { getOwner } from "discourse-common/lib/get-owner";
import GroupMessageSectionLink from "discourse/lib/sidebar/messages-section/group-message-section-link";
import PersonalMessageSectionLink from "discourse/lib/sidebar/messages-section/personal-message-section-link";
export const INBOX = "inbox";
const UNREAD = "unread";
const SENT = "sent";
const NEW = "new";
const ARCHIVE = "archive";
export const PERSONAL_MESSAGES_INBOXES = [INBOX, UNREAD, NEW, SENT, ARCHIVE];
export const GROUP_MESSAGES_INBOXES = [INBOX, UNREAD, NEW, ARCHIVE];
export default class SidebarMessagesSection extends GlimmerComponent {
constructor() {
super(...arguments);
this.appEvents.on(
"page:changed",
this,
this._refreshSectionLinksDisplayState
);
}
willDestroy() {
this.appEvents.off(
"page:changed",
this,
this._refreshSectionLinksDisplayState
);
}
_refreshSectionLinksDisplayState({
currentRouteName,
currentRouteParentName,
currentRouteParams,
}) {
const sectionLinks = [
...this.personalMessagesSectionLinks,
...this.groupMessagesSectionLinks,
];
if (currentRouteParentName !== "userPrivateMessages") {
sectionLinks.forEach((sectionLink) => {
sectionLink.collapse();
});
} else {
sectionLinks.forEach((sectionLink) => {
sectionLink.pageChanged(currentRouteName, currentRouteParams);
});
}
}
@cached
get personalMessagesSectionLinks() {
const links = [];
PERSONAL_MESSAGES_INBOXES.forEach((type) => {
links.push(
new PersonalMessageSectionLink({
currentUser: this.currentUser,
type,
})
);
});
return links;
}
@cached
get groupMessagesSectionLinks() {
const links = [];
this.currentUser.groupsWithMessages.forEach((group) => {
GROUP_MESSAGES_INBOXES.forEach((groupMessageLink) => {
links.push(
new GroupMessageSectionLink({
group,
type: groupMessageLink,
currentUser: this.currentUser,
})
);
});
});
return links;
}
@action
composePersonalMessage() {
const composerArgs = {

View File

@ -42,6 +42,8 @@ export function startPageTracking(router, appEvents, documentTitle) {
url,
title: documentTitle.getTitle(),
currentRouteName: router.currentRouteName,
currentRouteParams: router.currentRoute.params,
currentRouteParentName: router.currentRoute.parent?.name,
replacedOnlyQueryParams,
});
});

View File

@ -0,0 +1,80 @@
import I18n from "I18n";
import { tracked } from "@glimmer/tracking";
import { capitalize } from "@ember/string";
import { INBOX } from "discourse/components/sidebar/messages-section";
export default class GroupMessageSectionLink {
@tracked shouldDisplay = this._isInbox;
routeNames = new Set([
"userPrivateMessages.group",
"userPrivateMessages.groupUnread",
"userPrivateMessages.groupNew",
"userPrivateMessages.groupArchive",
]);
constructor({ group, type, currentUser, router }) {
this.group = group;
this.type = type;
this.currentUser = currentUser;
this.router = router;
}
get name() {
return `group-messages-${this.type}`;
}
get class() {
return this.group.name;
}
get route() {
if (this._isInbox) {
return "userPrivateMessages.group";
} else {
return `userPrivateMessages.group${capitalize(this.type)}`;
}
}
get currentWhen() {
if (this._isInbox) {
return [...this.routeNames].join(" ");
}
}
get models() {
return [this.currentUser, this.group.name];
}
get text() {
if (this._isInbox) {
return this.group.name;
} else {
return I18n.t(`sidebar.sections.messages.links.${this.type}`);
}
}
collapse() {
if (this._isInbox) {
return;
}
this.shouldDisplay = false;
}
pageChanged(currentRouteName, currentRouteParams) {
if (this._isInbox) {
return;
}
this.shouldDisplay =
this.routeNames.has(currentRouteName) &&
currentRouteParams.name.toLowerCase() === this.group.name.toLowerCase();
}
get _isInbox() {
return this.type === INBOX;
}
}

View File

@ -0,0 +1,68 @@
import I18n from "I18n";
import { tracked } from "@glimmer/tracking";
import { INBOX } from "discourse/components/sidebar/messages-section";
export default class PersonalMessageSectionLink {
@tracked shouldDisplay = this._isInbox;
routeNames = new Set([
"userPrivateMessages.index",
"userPrivateMessages.unread",
"userPrivateMessages.sent",
"userPrivateMessages.new",
"userPrivateMessages.archive",
]);
constructor({ currentUser, type, router }) {
this.currentUser = currentUser;
this.type = type;
this.router = router;
}
get name() {
return `personal-messages-${this.type}`;
}
get route() {
if (this._isInbox) {
return "userPrivateMessages.index";
} else {
return `userPrivateMessages.${this.type}`;
}
}
get currentWhen() {
if (this._isInbox) {
return [...this.routeNames].join(" ");
}
}
get model() {
return this.currentUser;
}
get text() {
return I18n.t(`sidebar.sections.messages.links.${this.type}`);
}
collapse() {
if (this._isInbox) {
return;
}
this.shouldDisplay = false;
}
pageChanged(currentRouteName) {
if (this._isInbox) {
return;
}
this.shouldDisplay = this.routeNames.has(currentRouteName);
}
get _isInbox() {
return this.type === INBOX;
}
}

View File

@ -8,7 +8,9 @@
<Sidebar::TagsSection />
{{/if}}
{{#if this.siteSettings.enable_personal_messages}}
<Sidebar::MessagesSection />
{{/if}}
</div>
</div>
{{/if}}

View File

@ -7,4 +7,31 @@
@headerLinkText={{i18n "sidebar.sections.messages.header_link_text"}}
@headerLinkTitle={{i18n "sidebar.sections.messages.header_link_title"}} >
{{#each this.personalMessagesSectionLinks as |personalMessageSectionLink|}}
{{#if personalMessageSectionLink.shouldDisplay}}
<Sidebar::SectionLink
@linkName={{personalMessageSectionLink.name}}
@route={{personalMessageSectionLink.route}}
@model={{personalMessageSectionLink.model}}
@currentWhen={{personalMessageSectionLink.currentWhen}}
@content={{personalMessageSectionLink.text}} />
{{/if}}
{{/each}}
{{#if (gt this.groupMessagesSectionLinks.length 0)}}
<hr>
{{#each this.groupMessagesSectionLinks as |groupMessageSectionLink|}}
{{#if groupMessageSectionLink.shouldDisplay}}
<Sidebar::SectionLink
@linkName={{groupMessageSectionLink.name}}
@class={{groupMessageSectionLink.class}}
@route={{groupMessageSectionLink.route}}
@models={{groupMessageSectionLink.models}}
@currentWhen={{groupMessageSectionLink.currentWhen}}
@content={{groupMessageSectionLink.text}} />
{{/if}}
{{/each}}
{{/if}}
</Sidebar::Section>

View File

@ -1,6 +1,6 @@
<div class="sidebar-section-link-wrapper">
<Sidebar::SectionLinkTo
@class={{concat "sidebar-section-link sidebar-section-link-" @linkName}}
@class={{concat @class (concat " sidebar-section-link sidebar-section-link-" @linkName)}}
@route={{@route}}
@query={{@query}}
@models={{if @model (array @model) (if @models @models (array))}}

View File

@ -4,14 +4,71 @@ import {
acceptance,
conditionalTest,
exists,
queryAll,
updateCurrentUser,
} from "discourse/tests/helpers/qunit-helpers";
import { isLegacyEmber } from "discourse-common/config/environment";
acceptance("Sidebar - Messages Section", function (needs) {
acceptance(
"Sidebar - Messages Section - enable_personal_messages disabled",
function (needs) {
needs.user({
experimental_sidebar_enabled: true,
});
needs.settings({
enable_personal_messages: false,
});
conditionalTest(
"clicking on section header button",
!isLegacyEmber(),
async function (assert) {
await visit("/");
assert.ok(
!exists(".sidebar-section-messages"),
"does not display messages section in sidebar"
);
}
);
}
);
acceptance(
"Sidebar - Messages Section - enable_personal_messages enabled",
function (needs) {
needs.user({
experimental_sidebar_enabled: true,
});
needs.pretender((server, helper) => {
[
"/topics/private-messages-new/:username.json",
"/topics/private-messages-unread/:username.json",
"/topics/private-messages-archive/:username.json",
"/topics/private-messages-sent/:username.json",
"/topics/private-messages-group/:username/:group_name/new.json",
"/topics/private-messages-group/:username/:group_name.json",
"/topics/private-messages-group/:username/:group_name/unread.json",
"/topics/private-messages-group/:username/:group_name/archive.json",
].forEach((url) => {
server.get(url, () => {
const topics = [
{ id: 1, posters: [] },
{ id: 2, posters: [] },
{ id: 3, posters: [] },
];
return helper.response({
topic_list: {
topics,
},
});
});
});
});
conditionalTest(
"clicking on section header button",
!isLegacyEmber(),
@ -41,4 +98,222 @@ acceptance("Sidebar - Messages Section", function (needs) {
);
}
);
});
conditionalTest(
"personal messages section links",
!isLegacyEmber(),
async function (assert) {
await visit("/");
assert.ok(
exists(
".sidebar-section-messages .sidebar-section-link-personal-messages-inbox"
),
"displays the personal message inbox link"
);
assert.strictEqual(
queryAll(".sidebar-section-messages .sidebar-section-link").length,
1,
"only displays the personal message inbox link"
);
await click(
".sidebar-section-messages .sidebar-section-link-personal-messages-inbox"
);
assert.ok(
exists(
".sidebar-section-messages .sidebar-section-link-personal-messages-inbox.active"
),
"personal message inbox link is marked as active"
);
assert.strictEqual(
queryAll(".sidebar-section-messages .sidebar-section-link").length,
5,
"expands and displays the links for personal messages"
);
}
);
["new", "archive", "sent", "unread"].forEach((type) => {
conditionalTest(
`${type} personal messages section link`,
!isLegacyEmber(),
async function (assert) {
await visit("/");
await click(
".sidebar-section-messages .sidebar-section-link-personal-messages-inbox"
);
await click(
`.sidebar-section-messages .sidebar-section-link-personal-messages-${type}`
);
assert.strictEqual(
currentURL(),
`/u/eviltrout/messages/${type}`,
`it should transition to user's ${type} personal messages`
);
assert.strictEqual(
queryAll(".sidebar-section-messages .sidebar-section-link.active")
.length,
2,
"only two links are marked as active in the sidebar"
);
assert.ok(
exists(
".sidebar-section-messages .sidebar-section-link-personal-messages-inbox.active"
),
"personal message inbox link is marked as active"
);
assert.ok(
exists(
`.sidebar-section-messages .sidebar-section-link-personal-messages-${type}.active`
),
`personal message ${type} link is marked as active`
);
}
);
});
conditionalTest(
"group messages section links",
!isLegacyEmber(),
async function (assert) {
updateCurrentUser({
groups: [
{
name: "group1",
has_messages: true,
},
{
name: "group2",
has_messages: false,
},
{
name: "group3",
has_messages: true,
},
],
});
await visit("/");
assert.ok(
exists(
".sidebar-section-messages .sidebar-section-link-group-messages-inbox.group1"
),
"displays group1 inbox link"
);
assert.ok(
exists(
".sidebar-section-messages .sidebar-section-link-group-messages-inbox.group3"
),
"displays group3 inbox link"
);
await visit("/u/eviltrout/messages/group/GrOuP1");
assert.strictEqual(
queryAll(".sidebar-section-messages .sidebar-section-link").length,
6,
"expands and displays the links for group1 group messages"
);
assert.strictEqual(
queryAll(".sidebar-section-messages .sidebar-section-link.group1")
.length,
4,
"expands the links for group1 group messages"
);
await click(
".sidebar-section-messages .sidebar-section-link-group-messages-inbox.group3"
);
assert.strictEqual(
queryAll(".sidebar-section-messages .sidebar-section-link.group1")
.length,
1,
"collapses the links for group1 group messages"
);
assert.strictEqual(
queryAll(".sidebar-section-messages .sidebar-section-link.group3")
.length,
4,
"expands the links for group3 group messages"
);
}
);
["new", "archive", "unread"].forEach((type) => {
conditionalTest(
`${type} group messages section link`,
!isLegacyEmber(),
async function (assert) {
updateCurrentUser({
groups: [
{
name: "group1",
has_messages: true,
},
{
name: "group2",
has_messages: false,
},
{
name: "group3",
has_messages: true,
},
],
});
await visit("/");
await click(
`.sidebar-section-messages .sidebar-section-link-group-messages-inbox.group1`
);
await click(
`.sidebar-section-messages .sidebar-section-link-group-messages-${type}.group1`
);
assert.strictEqual(
currentURL(),
`/u/eviltrout/messages/group/group1/${type}`,
`it should transition to user's ${type} personal messages`
);
assert.strictEqual(
queryAll(".sidebar-section-messages .sidebar-section-link.active")
.length,
2,
"only two links are marked as active in the sidebar"
);
assert.ok(
exists(
".sidebar-section-messages .sidebar-section-link-group-messages-inbox.group1.active"
),
"group1 group message inbox link is marked as active"
);
assert.ok(
exists(
`.sidebar-section-messages .sidebar-section-link-group-messages-${type}.group1.active`
),
`group1 group message ${type} link is marked as active`
);
}
);
});
}
);

View File

@ -145,4 +145,20 @@
color: var(--primary-medium);
}
}
.sidebar-section-content {
hr {
margin: 0em 1.5em;
}
}
.sidebar-section-link-personal-messages-sent,
.sidebar-section-link-personal-messages-new,
.sidebar-section-link-personal-messages-archive,
.sidebar-section-link-personal-messages-unread,
.sidebar-section-link-group-messages-new,
.sidebar-section-link-group-messages-unread,
.sidebar-section-link-group-messages-archive {
margin-left: 0.5em;
}
}

View File

@ -4045,6 +4045,12 @@ en:
header_link_title: "personal messages"
header_link_text: "Messages"
header_action_title: "create a personal message"
links:
inbox: "Inbox"
sent: "Sent"
new: "New"
unread: "Unread"
archive: "Archive"
tags:
no_tracked_tags: "You are not tracking any tags."
header_link_title: "all tags"