mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 12:57:29 +08:00
FEATURE: New and Unread messages for user personal messages. (#13603)
* FEATURE: New and Unread messages for user personal messages. Co-authored-by: awesomerobot <kris.aubuchon@discourse.org>
This commit is contained in:
parent
fe3e18f981
commit
016efeadf6
|
@ -154,10 +154,14 @@ export default Controller.extend(bufferedProperty("model"), {
|
|||
showCategoryChooser: not("model.isPrivateMessage"),
|
||||
|
||||
gotoInbox(name) {
|
||||
let url = userPath(this.get("currentUser.username_lower") + "/messages");
|
||||
let url = userPath(`${this.get("currentUser.username_lower")}/messages`);
|
||||
|
||||
if (name) {
|
||||
url = url + "/group/" + name;
|
||||
url = `${url}/group/${name}`;
|
||||
} else {
|
||||
url = `${url}/personal`;
|
||||
}
|
||||
|
||||
DiscourseURL.routeTo(url);
|
||||
},
|
||||
|
||||
|
|
|
@ -3,6 +3,10 @@ import { action } from "@ember/object";
|
|||
import { alias, and, equal } from "@ember/object/computed";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import { VIEW_NAME_WARNINGS } from "discourse/routes/user-private-messages-warnings";
|
||||
import I18n from "I18n";
|
||||
|
||||
export const PERSONAL_INBOX = "__personal_inbox__";
|
||||
const ALL_INBOX = "__all_inbox__";
|
||||
|
||||
export default Controller.extend({
|
||||
user: controller(),
|
||||
|
@ -10,19 +14,101 @@ export default Controller.extend({
|
|||
pmView: false,
|
||||
viewingSelf: alias("user.viewingSelf"),
|
||||
isGroup: equal("pmView", "groups"),
|
||||
group: null,
|
||||
groupFilter: alias("group.name"),
|
||||
currentPath: alias("router._router.currentPath"),
|
||||
pmTaggingEnabled: alias("site.can_tag_pms"),
|
||||
tagId: null,
|
||||
|
||||
showNewPM: and("user.viewingSelf", "currentUser.can_send_private_messages"),
|
||||
|
||||
@discourseComputed("inboxes", "isAllInbox")
|
||||
displayGlobalFilters(inboxes, isAllInbox) {
|
||||
if (inboxes.length === 0) {
|
||||
return true;
|
||||
}
|
||||
if (inboxes.length && isAllInbox) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
@discourseComputed("inboxes")
|
||||
sectionClass(inboxes) {
|
||||
const defaultClass = "user-secondary-navigation user-messages";
|
||||
|
||||
return inboxes.length
|
||||
? `${defaultClass} user-messages-inboxes`
|
||||
: defaultClass;
|
||||
},
|
||||
|
||||
@discourseComputed("pmView")
|
||||
isPersonalInbox(pmView) {
|
||||
return pmView && pmView.startsWith("personal");
|
||||
},
|
||||
|
||||
@discourseComputed("isPersonalInbox", "group.name")
|
||||
isAllInbox(isPersonalInbox, groupName) {
|
||||
return !this.isPersonalInbox && !groupName;
|
||||
},
|
||||
|
||||
@discourseComputed("isPersonalInbox", "group.name")
|
||||
selectedInbox(isPersonalInbox, groupName) {
|
||||
if (groupName) {
|
||||
return groupName;
|
||||
}
|
||||
|
||||
return isPersonalInbox ? PERSONAL_INBOX : ALL_INBOX;
|
||||
},
|
||||
|
||||
@discourseComputed("viewingSelf", "pmView", "currentUser.admin")
|
||||
showWarningsWarning(viewingSelf, pmView, isAdmin) {
|
||||
return pmView === VIEW_NAME_WARNINGS && !viewingSelf && !isAdmin;
|
||||
},
|
||||
|
||||
@discourseComputed("model.groups")
|
||||
inboxes(groups) {
|
||||
const groupsWithMessages = groups?.filter((group) => {
|
||||
return group.has_messages;
|
||||
});
|
||||
|
||||
if (!groupsWithMessages || groupsWithMessages.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const inboxes = [];
|
||||
|
||||
inboxes.push({
|
||||
id: ALL_INBOX,
|
||||
name: I18n.t("user.messages.all"),
|
||||
});
|
||||
|
||||
inboxes.push({
|
||||
id: PERSONAL_INBOX,
|
||||
name: I18n.t("user.messages.personal"),
|
||||
icon: "envelope",
|
||||
});
|
||||
|
||||
groupsWithMessages.forEach((group) => {
|
||||
inboxes.push({ id: group.name, name: group.name, icon: "users" });
|
||||
});
|
||||
|
||||
return inboxes;
|
||||
},
|
||||
|
||||
@action
|
||||
changeGroupNotificationLevel(notificationLevel) {
|
||||
this.group.setNotification(notificationLevel, this.get("user.model.id"));
|
||||
},
|
||||
|
||||
@action
|
||||
updateInbox(inbox) {
|
||||
if (inbox === ALL_INBOX) {
|
||||
this.transitionToRoute("userPrivateMessages.index");
|
||||
} else if (inbox === PERSONAL_INBOX) {
|
||||
this.transitionToRoute("userPrivateMessages.personal");
|
||||
} else {
|
||||
this.transitionToRoute("userPrivateMessages.group", inbox);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
export function findOrResetCachedTopicList(session, filter) {
|
||||
const lastTopicList = session.get("topicList");
|
||||
|
||||
if (lastTopicList && lastTopicList.filter === filter) {
|
||||
return lastTopicList;
|
||||
} else {
|
||||
|
|
|
@ -140,11 +140,20 @@ export default function () {
|
|||
"userPrivateMessages",
|
||||
{ path: "/messages", resetNamespace: true },
|
||||
function () {
|
||||
this.route("sent");
|
||||
this.route("new");
|
||||
this.route("unread");
|
||||
this.route("archive");
|
||||
this.route("sent");
|
||||
this.route("personal");
|
||||
this.route("personalSent", { path: "personal/sent" });
|
||||
this.route("personalNew", { path: "personal/new" });
|
||||
this.route("personalUnread", { path: "personal/unread" });
|
||||
this.route("personalArchive", { path: "personal/archive" });
|
||||
this.route("warnings");
|
||||
this.route("group", { path: "group/:name" });
|
||||
this.route("groupArchive", { path: "group/:name/archive" });
|
||||
this.route("groupNew", { path: "group/:name/new" });
|
||||
this.route("groupUnread", { path: "group/:name/unread" });
|
||||
this.route("tags");
|
||||
this.route("tagsShow", { path: "tags/:id" });
|
||||
}
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
import I18n from "I18n";
|
||||
import createPMRoute from "discourse/routes/build-private-messages-route";
|
||||
import { findOrResetCachedTopicList } from "discourse/lib/cached-topic-list";
|
||||
|
||||
export default (viewName, channel) => {
|
||||
return createPMRoute("groups", "private-messages-groups").extend({
|
||||
groupName: null,
|
||||
|
||||
titleToken() {
|
||||
const groupName = this.groupName;
|
||||
|
||||
if (groupName) {
|
||||
let title = groupName.capitalize();
|
||||
|
||||
if (viewName !== "index") {
|
||||
title = `${title} ${I18n.t("user.messages." + viewName)}`;
|
||||
}
|
||||
|
||||
return [title, I18n.t(`user.private_messages`)];
|
||||
}
|
||||
},
|
||||
|
||||
model(params) {
|
||||
const username = this.modelFor("user").get("username_lower");
|
||||
let filter = `topics/private-messages-group/${username}/${params.name}`;
|
||||
|
||||
if (viewName !== "index") {
|
||||
filter = `${filter}/${viewName}`;
|
||||
}
|
||||
|
||||
const lastTopicList = findOrResetCachedTopicList(this.session, filter);
|
||||
|
||||
return lastTopicList
|
||||
? lastTopicList
|
||||
: this.store.findFiltered("topicList", { filter });
|
||||
},
|
||||
|
||||
afterModel(model) {
|
||||
const filters = model.get("filter").split("/");
|
||||
let groupName;
|
||||
|
||||
if (viewName !== "index") {
|
||||
groupName = filters[filters.length - 2];
|
||||
} else {
|
||||
groupName = filters.pop();
|
||||
}
|
||||
|
||||
const group = this.modelFor("user")
|
||||
.get("groups")
|
||||
.filterBy("name", groupName)[0];
|
||||
|
||||
this.setProperties({ groupName: groupName, group });
|
||||
},
|
||||
|
||||
setupController() {
|
||||
this._super.apply(this, arguments);
|
||||
this.controllerFor("user-private-messages").set("group", this.group);
|
||||
|
||||
if (channel) {
|
||||
this.controllerFor("user-topics-list").subscribe(
|
||||
`/private-messages/group/${this.get(
|
||||
"groupName"
|
||||
).toLowerCase()}/${channel}`
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
|
@ -23,7 +23,9 @@ export default (viewName, path, channel) => {
|
|||
model() {
|
||||
const filter =
|
||||
"topics/" + path + "/" + this.modelFor("user").get("username_lower");
|
||||
|
||||
const lastTopicList = findOrResetCachedTopicList(this.session, filter);
|
||||
|
||||
return lastTopicList
|
||||
? lastTopicList
|
||||
: this.store.findFiltered("topicList", { filter });
|
||||
|
@ -49,6 +51,7 @@ export default (viewName, path, channel) => {
|
|||
this.controllerFor("user-private-messages").setProperties({
|
||||
archive: false,
|
||||
pmView: viewName,
|
||||
group: null,
|
||||
});
|
||||
|
||||
this.searchService.set("contextType", "private_messages");
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
import createPMRoute from "discourse/routes/build-private-messages-route";
|
||||
|
||||
export default createPMRoute("archive", "private-messages-archive", "archive");
|
||||
export default createPMRoute(
|
||||
"archive",
|
||||
"private-messages-all-archive",
|
||||
"archive"
|
||||
);
|
||||
|
|
|
@ -1,48 +1,3 @@
|
|||
import I18n from "I18n";
|
||||
import createPMRoute from "discourse/routes/build-private-messages-route";
|
||||
import { findOrResetCachedTopicList } from "discourse/lib/cached-topic-list";
|
||||
import createPMRoute from "discourse/routes/build-private-messages-group-route";
|
||||
|
||||
export default createPMRoute("groups", "private-messages-groups").extend({
|
||||
groupName: null,
|
||||
|
||||
titleToken() {
|
||||
const groupName = this.groupName;
|
||||
|
||||
if (groupName) {
|
||||
return [
|
||||
`${groupName.capitalize()} ${I18n.t("user.messages.archive")}`,
|
||||
I18n.t("user.private_messages"),
|
||||
];
|
||||
}
|
||||
},
|
||||
|
||||
model(params) {
|
||||
const username = this.modelFor("user").get("username_lower");
|
||||
const filter = `topics/private-messages-group/${username}/${params.name}/archive`;
|
||||
const lastTopicList = findOrResetCachedTopicList(this.session, filter);
|
||||
return lastTopicList
|
||||
? lastTopicList
|
||||
: this.store.findFiltered("topicList", { filter });
|
||||
},
|
||||
|
||||
afterModel(model) {
|
||||
const split = model.get("filter").split("/");
|
||||
const groupName = split[split.length - 2];
|
||||
this.set("groupName", groupName);
|
||||
const group = this.modelFor("user")
|
||||
.get("groups")
|
||||
.filterBy("name", groupName)[0];
|
||||
this.controllerFor("user-private-messages").set("group", group);
|
||||
},
|
||||
|
||||
setupController(controller, model) {
|
||||
this._super.apply(this, arguments);
|
||||
const split = model.get("filter").split("/");
|
||||
const group = split[split.length - 2];
|
||||
this.controllerFor("user-private-messages").set("groupFilter", group);
|
||||
this.controllerFor("user-private-messages").set("archive", true);
|
||||
this.controllerFor("user-topics-list").subscribe(
|
||||
`/private-messages/group/${group}/archive`
|
||||
);
|
||||
},
|
||||
});
|
||||
export default createPMRoute("archive", "archive");
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
import createPMRoute from "discourse/routes/build-private-messages-group-route";
|
||||
|
||||
export default createPMRoute("new", null /* no message bus notifications */);
|
|
@ -0,0 +1,3 @@
|
|||
import createPMRoute from "discourse/routes/build-private-messages-group-route";
|
||||
|
||||
export default createPMRoute("unread", null /* no message bus notifications */);
|
|
@ -1,42 +1,3 @@
|
|||
import I18n from "I18n";
|
||||
import createPMRoute from "discourse/routes/build-private-messages-route";
|
||||
import { findOrResetCachedTopicList } from "discourse/lib/cached-topic-list";
|
||||
import createPMRoute from "discourse/routes/build-private-messages-group-route";
|
||||
|
||||
export default createPMRoute("groups", "private-messages-groups").extend({
|
||||
groupName: null,
|
||||
|
||||
titleToken() {
|
||||
const groupName = this.groupName;
|
||||
if (groupName) {
|
||||
return [groupName.capitalize(), I18n.t("user.private_messages")];
|
||||
}
|
||||
},
|
||||
|
||||
model(params) {
|
||||
const username = this.modelFor("user").get("username_lower");
|
||||
const filter = `topics/private-messages-group/${username}/${params.name}`;
|
||||
const lastTopicList = findOrResetCachedTopicList(this.session, filter);
|
||||
return lastTopicList
|
||||
? lastTopicList
|
||||
: this.store.findFiltered("topicList", { filter });
|
||||
},
|
||||
|
||||
afterModel(model) {
|
||||
const groupName = model.get("filter").split("/").pop();
|
||||
this.set("groupName", groupName);
|
||||
const group = this.modelFor("user")
|
||||
.get("groups")
|
||||
.filterBy("name", groupName)[0];
|
||||
this.controllerFor("user-private-messages").set("group", group);
|
||||
},
|
||||
|
||||
setupController(controller, model) {
|
||||
this._super.apply(this, arguments);
|
||||
const group = model.get("filter").split("/").pop();
|
||||
this.controllerFor("user-private-messages").set("groupFilter", group);
|
||||
this.controllerFor("user-private-messages").set("archive", false);
|
||||
this.controllerFor("user-topics-list").subscribe(
|
||||
`/private-messages/group/${group}`
|
||||
);
|
||||
},
|
||||
});
|
||||
export default createPMRoute("index", "inbox");
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
import createPMRoute from "discourse/routes/build-private-messages-route";
|
||||
|
||||
export default createPMRoute("index", "private-messages", "inbox");
|
||||
export default createPMRoute("index", "private-messages-all", "inbox");
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
import createPMRoute from "discourse/routes/build-private-messages-route";
|
||||
|
||||
export default createPMRoute(
|
||||
"new",
|
||||
"private-messages-all-new",
|
||||
null /* no message bus notifications */
|
||||
);
|
|
@ -0,0 +1,3 @@
|
|||
import createPMRoute from "discourse/routes/build-private-messages-route";
|
||||
|
||||
export default createPMRoute("personal", "private-messages-archive", "archive");
|
|
@ -0,0 +1,7 @@
|
|||
import createPMRoute from "discourse/routes/build-private-messages-route";
|
||||
|
||||
export default createPMRoute(
|
||||
"personal",
|
||||
"private-messages-new",
|
||||
null /* no message bus notifications */
|
||||
);
|
|
@ -0,0 +1,3 @@
|
|||
import createPMRoute from "discourse/routes/build-private-messages-route";
|
||||
|
||||
export default createPMRoute("personal", "private-messages-sent", "sent");
|
|
@ -0,0 +1,7 @@
|
|||
import createPMRoute from "discourse/routes/build-private-messages-route";
|
||||
|
||||
export default createPMRoute(
|
||||
"personal",
|
||||
"private-messages-unread",
|
||||
null /* no message bus notifications */
|
||||
);
|
|
@ -0,0 +1,3 @@
|
|||
import createPMRoute from "discourse/routes/build-private-messages-route";
|
||||
|
||||
export default createPMRoute("personal", "private-messages", "inbox");
|
|
@ -1,3 +1,7 @@
|
|||
import createPMRoute from "discourse/routes/build-private-messages-route";
|
||||
|
||||
export default createPMRoute("sent", "private-messages-sent", "sent");
|
||||
export default createPMRoute(
|
||||
"sent",
|
||||
"private-messages-all-sent",
|
||||
null /* no message bus notifications */
|
||||
);
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
import createPMRoute from "discourse/routes/build-private-messages-route";
|
||||
|
||||
export default createPMRoute(
|
||||
"unread",
|
||||
"private-messages-all-unread",
|
||||
null /* no message bus notifications */
|
||||
);
|
|
@ -12,9 +12,11 @@ export default DiscourseRoute.extend({
|
|||
},
|
||||
|
||||
setupController(controller, user) {
|
||||
const composerController = this.controllerFor("composer");
|
||||
controller.set("model", user);
|
||||
|
||||
if (this.currentUser) {
|
||||
const composerController = this.controllerFor("composer");
|
||||
|
||||
Draft.get("new_private_message").then((data) => {
|
||||
if (data.draft) {
|
||||
composerController.open({
|
||||
|
|
|
@ -1,81 +1,148 @@
|
|||
{{#d-section class="user-secondary-navigation" pageClass="user-messages"}}
|
||||
{{#unless site.mobileView}}
|
||||
{{#if showNewPM}}
|
||||
{{d-button class="btn-primary new-private-message" action=(route-action "composePrivateMessage") icon="envelope" label="user.new_private_message"}}
|
||||
{{/if}}
|
||||
{{/unless}}
|
||||
{{#d-section class=sectionClass pageClass="user-messages"}}
|
||||
{{#if inboxes.length}}
|
||||
<div class="inboxes-controls">
|
||||
{{combo-box
|
||||
content=inboxes
|
||||
classNames="user-messages-inboxes-drop"
|
||||
value=selectedInbox
|
||||
onChange=(action "updateInbox")
|
||||
options=(hash
|
||||
filterable=true
|
||||
)
|
||||
}}
|
||||
{{#if (and group site.mobileView)}}
|
||||
{{group-notifications-button
|
||||
value=group.group_user.notification_level
|
||||
onChange=(action "changeGroupNotificationLevel")
|
||||
}}
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#mobile-nav class="messages-nav" desktopClass="nav-stacked action-list"}}
|
||||
<li class="noGlyph">
|
||||
{{#link-to "userPrivateMessages.index" model}}
|
||||
{{i18n "user.messages.inbox"}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
<li class="noGlyph">
|
||||
{{#link-to "userPrivateMessages.sent" model}}
|
||||
{{i18n "user.messages.sent"}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
<li class="noGlyph">
|
||||
{{#link-to "userPrivateMessages.archive" model}}
|
||||
{{i18n "user.messages.archive"}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
{{plugin-outlet name="user-messages-nav" connectorTagName="li" args=(hash model=model)}}
|
||||
{{#each model.groups as |group|}}
|
||||
{{#if group.has_messages}}
|
||||
<li>
|
||||
{{#link-to "userPrivateMessages.group" group.name}}
|
||||
{{d-icon "users"}}
|
||||
{{capitalize-string group.name}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
<li class="archive">
|
||||
{{#link-to "userPrivateMessages.groupArchive" group.name}}
|
||||
{{i18n "user.messages.archive"}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
|
||||
{{#if pmTaggingEnabled}}
|
||||
{{#if isAllInbox}}
|
||||
<li class="noGlyph">
|
||||
{{#link-to "userPrivateMessages.tags" model}}
|
||||
{{i18n "user.messages.tags"}}
|
||||
{{#link-to "userPrivateMessages.index" model}}
|
||||
{{i18n "user.messages.latest"}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
{{#if tagId}}
|
||||
<li class="archive">
|
||||
{{#link-to "userPrivateMessages.tagsShow" tagId}}
|
||||
{{tagId}}
|
||||
<li class="noGlyph">
|
||||
{{#link-to "userPrivateMessages.sent" model}}
|
||||
{{i18n "user.messages.sent"}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
<li class="noGlyph">
|
||||
{{#link-to "userPrivateMessages.new" model}}
|
||||
{{i18n "user.messages.new"}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
<li class="noGlyph">
|
||||
{{#link-to "userPrivateMessages.unread" model}}
|
||||
{{i18n "user.messages.unread"}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
<li class="noGlyph">
|
||||
{{#link-to "userPrivateMessages.archive" model}}
|
||||
{{i18n "user.messages.archive"}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
{{/if}}
|
||||
|
||||
{{#if group}}
|
||||
<li class="noGlyph">
|
||||
{{#link-to "userPrivateMessages.group" group.name}}
|
||||
{{i18n "user.messages.latest"}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
<li class="noGlyph">
|
||||
{{#link-to "userPrivateMessages.groupNew" group.name}}
|
||||
{{i18n "user.messages.new"}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
<li class="noGlyph">
|
||||
{{#link-to "userPrivateMessages.groupUnread" group.name}}
|
||||
{{i18n "user.messages.unread"}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
<li class="noGlyph">
|
||||
{{#link-to "userPrivateMessages.groupArchive" group.name}}
|
||||
{{i18n "user.messages.archive"}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
{{/if}}
|
||||
|
||||
{{#if isPersonalInbox}}
|
||||
<li class="noGlyph">
|
||||
{{#link-to "userPrivateMessages.personal" model}}
|
||||
{{i18n "user.messages.latest"}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
<li class="noGlyph">
|
||||
{{#link-to "userPrivateMessages.personalSent" model}}
|
||||
{{i18n "user.messages.sent"}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
<li class="noGlyph">
|
||||
{{#link-to "userPrivateMessages.personalNew" model}}
|
||||
{{i18n "user.messages.new"}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
<li class="noGlyph">
|
||||
{{#link-to "userPrivateMessages.personalUnread" model}}
|
||||
{{i18n "user.messages.unread"}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
<li class="noGlyph">
|
||||
{{#link-to "userPrivateMessages.personalArchive" model}}
|
||||
{{i18n "user.messages.archive"}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
{{/if}}
|
||||
|
||||
{{#if displayGlobalFilters}}
|
||||
{{#if pmTaggingEnabled}}
|
||||
<li class="noGlyph tags">
|
||||
{{#link-to "userPrivateMessages.tags" model}}
|
||||
{{i18n "user.messages.tags"}}
|
||||
{{/link-to}}
|
||||
|
||||
{{#if tagId}}
|
||||
<li class="archive">
|
||||
{{#link-to "userPrivateMessages.tagsShow" tagId}}
|
||||
{{tagId}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
{{/if}}
|
||||
</li>
|
||||
{{/if}}
|
||||
|
||||
{{plugin-outlet name="user-messages-nav" connectorTagName="li" args=(hash model=model)}}
|
||||
{{/if}}
|
||||
{{/mobile-nav}}
|
||||
{{/d-section}}
|
||||
|
||||
<section class="user-content">
|
||||
<div class="list-actions">
|
||||
{{#if site.mobileView}}
|
||||
{{#if showNewPM}}
|
||||
{{d-button
|
||||
class="btn-primary new-private-message"
|
||||
action=(route-action "composePrivateMessage")
|
||||
icon="envelope"
|
||||
label="user.new_private_message"}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{#if (and site.mobileView showNewPM)}}
|
||||
{{d-button class="btn-primary new-private-message" action=(route-action "composePrivateMessage") icon="envelope" label="user.new_private_message"}}
|
||||
{{/if}}
|
||||
|
||||
{{#if isGroup}}
|
||||
{{#unless site.mobileView}}
|
||||
<section class="user-additional-controls">
|
||||
{{#if group}}
|
||||
{{group-notifications-button
|
||||
value=group.group_user.notification_level
|
||||
onChange=(action "changeGroupNotificationLevel")
|
||||
}}
|
||||
{{/if}}
|
||||
</div>
|
||||
{{#if showNewPM}}
|
||||
{{d-button class="btn-primary new-private-message" action=(route-action "composePrivateMessage") icon="envelope" label="user.new_private_message"}}
|
||||
{{/if}}
|
||||
</section>
|
||||
{{/unless}}
|
||||
|
||||
<section class="user-content">
|
||||
{{#if showWarningsWarning}}
|
||||
<div class="alert alert-info">{{html-safe (i18n "admin.user.warnings_list_warning")}}</div>
|
||||
{{/if}}
|
||||
|
||||
{{outlet}}
|
||||
</section>
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
import {
|
||||
acceptance,
|
||||
count,
|
||||
exists,
|
||||
} from "discourse/tests/helpers/qunit-helpers";
|
||||
import { visit } from "@ember/test-helpers";
|
||||
import { test } from "qunit";
|
||||
import selectKit from "discourse/tests/helpers/select-kit-helper";
|
||||
import { PERSONAL_INBOX } from "discourse/controllers/user-private-messages";
|
||||
|
||||
acceptance(
|
||||
"User Private Messages - user with no group messages",
|
||||
function (needs) {
|
||||
needs.user();
|
||||
|
||||
needs.site({
|
||||
can_tag_pms: true,
|
||||
});
|
||||
|
||||
test("viewing messages", async function (assert) {
|
||||
await visit("/u/eviltrout/messages");
|
||||
|
||||
assert.equal(count(".topic-list-item"), 1, "displays the topic list");
|
||||
|
||||
assert.ok(
|
||||
!exists(".user-messages-inboxes-drop"),
|
||||
"does not display inboxes dropdown"
|
||||
);
|
||||
|
||||
assert.ok(exists(".messages-nav .tags"), "displays the tags filter");
|
||||
|
||||
assert.ok(
|
||||
!exists(".group-notifications-button"),
|
||||
"displays the group notifications button"
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
acceptance(
|
||||
"User Private Messages - user with group messages",
|
||||
function (needs) {
|
||||
needs.user();
|
||||
|
||||
needs.site({
|
||||
can_tag_pms: true,
|
||||
});
|
||||
|
||||
needs.pretender((server, helper) => {
|
||||
server.get("/topics/private-messages-all/:username.json", () => {
|
||||
return helper.response({
|
||||
topic_list: {
|
||||
topics: [
|
||||
{ id: 1, posters: [] },
|
||||
{ id: 2, posters: [] },
|
||||
{ id: 3, posters: [] },
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
server.get(
|
||||
"/topics/private-messages-group/:username/:group_name.json",
|
||||
() => {
|
||||
return helper.response({
|
||||
topic_list: {
|
||||
topics: [
|
||||
{ id: 1, posters: [] },
|
||||
{ id: 2, posters: [] },
|
||||
],
|
||||
},
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test("viewing messages", async function (assert) {
|
||||
await visit("/u/charlie/messages");
|
||||
|
||||
assert.equal(
|
||||
count(".topic-list-item"),
|
||||
3,
|
||||
"displays the right topic list"
|
||||
);
|
||||
|
||||
assert.ok(
|
||||
exists(".user-messages-inboxes-drop"),
|
||||
"displays inboxes dropdown"
|
||||
);
|
||||
|
||||
assert.ok(exists(".messages-nav .tags"), "displays the tags filter");
|
||||
|
||||
await selectKit(".user-messages-inboxes-drop").expand();
|
||||
await selectKit(".user-messages-inboxes-drop").selectRowByValue(
|
||||
PERSONAL_INBOX
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
count(".topic-list-item"),
|
||||
1,
|
||||
"displays the right topic list"
|
||||
);
|
||||
|
||||
assert.ok(
|
||||
!exists(".messages-nav .tags"),
|
||||
"does not display the tags filter"
|
||||
);
|
||||
|
||||
await selectKit(".user-messages-inboxes-drop").expand();
|
||||
await selectKit(".user-messages-inboxes-drop").selectRowByValue(
|
||||
"awesome_group"
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
count(".topic-list-item"),
|
||||
2,
|
||||
"displays the right topic list"
|
||||
);
|
||||
|
||||
assert.ok(
|
||||
exists(".group-notifications-button"),
|
||||
"displays the group notifications button"
|
||||
);
|
||||
|
||||
assert.ok(
|
||||
!exists(".messages-nav .tags"),
|
||||
"does not display the tags filter"
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
|
@ -38,11 +38,6 @@ acceptance("User Routes", function (needs) {
|
|||
assert.ok($("body.user-invites-page").length, "has the body class");
|
||||
});
|
||||
|
||||
test("Messages", async function (assert) {
|
||||
await visit("/u/eviltrout/messages");
|
||||
assert.ok($("body.user-messages-page").length, "has the body class");
|
||||
});
|
||||
|
||||
test("Notifications", async function (assert) {
|
||||
await visit("/u/eviltrout/notifications");
|
||||
assert.ok($("body.user-notifications-page").length, "has the body class");
|
||||
|
|
|
@ -2648,6 +2648,33 @@ export default {
|
|||
default_notification_level: 3,
|
||||
membership_request_template: null,
|
||||
},
|
||||
{
|
||||
id: 14,
|
||||
automatic: false,
|
||||
name: "awesome_group",
|
||||
display_name: "awesome_group",
|
||||
user_count: 3,
|
||||
mentionable_level: 0,
|
||||
messageable_level: 0,
|
||||
visibility_level: 0,
|
||||
automatic_membership_email_domains: null,
|
||||
primary_group: false,
|
||||
title: null,
|
||||
grant_trust_level: null,
|
||||
incoming_email: null,
|
||||
has_messages: true,
|
||||
flair_url: null,
|
||||
flair_bg_color: null,
|
||||
flair_color: null,
|
||||
bio_raw: null,
|
||||
bio_cooked: null,
|
||||
public_admission: false,
|
||||
public_exit: false,
|
||||
allow_membership_requests: false,
|
||||
full_name: null,
|
||||
default_notification_level: 3,
|
||||
membership_request_template: null,
|
||||
},
|
||||
],
|
||||
group_users: [
|
||||
{ group_id: 10, user_id: 5, notification_level: 3 },
|
||||
|
|
|
@ -207,12 +207,14 @@ export function applyDefaultHandlers(pretender) {
|
|||
});
|
||||
});
|
||||
|
||||
pretender.get("/topics/private-messages/eviltrout.json", () => {
|
||||
return response(fixturesByUrl["/topics/private-messages/eviltrout.json"]);
|
||||
});
|
||||
|
||||
pretender.get("/topics/private-messages-warnings/eviltrout.json", () => {
|
||||
return response(fixturesByUrl["/topics/private-messages/eviltrout.json"]);
|
||||
[
|
||||
"/topics/private-messages-all/:username.json",
|
||||
"/topics/private-messages/:username.json",
|
||||
"/topics/private-messages-warnings/eviltrout.json",
|
||||
].forEach((url) => {
|
||||
pretender.get(url, () => {
|
||||
return response(fixturesByUrl["/topics/private-messages/eviltrout.json"]);
|
||||
});
|
||||
});
|
||||
|
||||
pretender.get("/topics/feature_stats.json", () => {
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
.user-content {
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
.user-additional-controls + .user-content,
|
||||
.user-secondary-navigation + .user-content {
|
||||
grid-column-start: 2;
|
||||
|
|
|
@ -66,12 +66,10 @@
|
|||
.nav-stacked {
|
||||
@extend %nav;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
background: var(--primary-low);
|
||||
|
||||
li {
|
||||
border-bottom: 1px solid var(--primary-low);
|
||||
position: relative;
|
||||
|
||||
&:last-of-type {
|
||||
border-bottom: 0;
|
||||
|
@ -89,6 +87,7 @@
|
|||
line-height: $line-height-small;
|
||||
cursor: pointer;
|
||||
color: var(--primary);
|
||||
@include ellipsis;
|
||||
|
||||
&.active {
|
||||
color: var(--secondary);
|
||||
|
|
|
@ -6,10 +6,6 @@
|
|||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.show-mores {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
.form-horizontal .control-group.category {
|
||||
|
@ -20,10 +16,20 @@
|
|||
font-size: 1.5em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.user-secondary-navigation {
|
||||
min-width: 150px;
|
||||
|
||||
.combo-box {
|
||||
width: 100%;
|
||||
&:not(:last-of-type) {
|
||||
margin-bottom: 0.875em;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-stacked {
|
||||
background-color: transparent;
|
||||
margin: 0;
|
||||
|
||||
li {
|
||||
border-bottom: none;
|
||||
|
@ -47,6 +53,42 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.select-kit + .messages-nav {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.inboxes-controls {
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
|
||||
&.user-messages {
|
||||
--left-padding: 0.8em;
|
||||
.user-messages-inboxes-drop {
|
||||
padding: 0 1em 0 0;
|
||||
|
||||
.select-kit-header {
|
||||
padding-left: var(--left-padding);
|
||||
}
|
||||
|
||||
.select-kit-selected-name {
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-stacked {
|
||||
a {
|
||||
padding-left: calc(
|
||||
var(--left-padding) - 1px
|
||||
); // 1px accounts for border on select-kit elements above
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.user-additional-controls {
|
||||
button {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.user-content {
|
||||
|
@ -226,6 +268,20 @@ table.user-invite-list {
|
|||
}
|
||||
}
|
||||
|
||||
.user-messages-page {
|
||||
.topic-list th {
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
.show-mores {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
.user-messages {
|
||||
margin-right: 0.2em;
|
||||
}
|
||||
|
||||
.user-preferences {
|
||||
padding-top: 10px;
|
||||
padding-left: 30px;
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-template-rows: auto auto auto;
|
||||
grid-row-gap: 20px;
|
||||
grid-column-gap: 16px;
|
||||
grid-gap: 16px;
|
||||
.user-primary-navigation {
|
||||
grid-column-start: 1;
|
||||
grid-row-start: 1;
|
||||
|
@ -30,6 +29,71 @@
|
|||
grid-row-start: 3;
|
||||
grid-column-start: 1;
|
||||
}
|
||||
|
||||
// specific to messages
|
||||
|
||||
.user-messages.user-messages-inboxes {
|
||||
grid-row-start: 2;
|
||||
grid-column-start: 1;
|
||||
grid-column-end: 3;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 16px;
|
||||
|
||||
+ .user-additional-controls {
|
||||
grid-row-start: 2;
|
||||
grid-column-start: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.inboxes-controls {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.user-messages-inboxes-drop {
|
||||
padding: 0;
|
||||
flex: 1 1 auto;
|
||||
.select-kit-header {
|
||||
padding: 8px 10px;
|
||||
|
||||
.caret-icon {
|
||||
color: var(--primary-medium);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.messages-nav {
|
||||
grid-column-start: 2;
|
||||
grid-column-end: 3;
|
||||
grid-row-start: 1;
|
||||
}
|
||||
|
||||
.new-private-message {
|
||||
grid-row-start: 1;
|
||||
grid-column-start: 2;
|
||||
}
|
||||
|
||||
.group-notifications-button {
|
||||
margin-left: 8px;
|
||||
|
||||
.select-kit-header {
|
||||
height: 100%;
|
||||
|
||||
.selected-name .name {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.user-messages-page {
|
||||
.paginated-topics-list {
|
||||
margin-top: 0;
|
||||
}
|
||||
.show-mores {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.user-main {
|
||||
|
@ -166,6 +230,10 @@
|
|||
flex: 1 1 25%;
|
||||
margin-left: auto;
|
||||
|
||||
.btn {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
|
@ -223,6 +291,7 @@
|
|||
|
||||
.user-main .collapsed-info.about .details {
|
||||
display: flex;
|
||||
margin-bottom: 16px;
|
||||
.user-profile-avatar {
|
||||
margin: 0;
|
||||
flex: 0 0 auto;
|
||||
|
|
|
@ -146,35 +146,27 @@ class ListController < ApplicationController
|
|||
end
|
||||
|
||||
def self.generate_message_route(action)
|
||||
case action
|
||||
when :private_messages_tag
|
||||
define_method("#{action}") do
|
||||
raise Discourse::NotFound if !guardian.can_tag_pms?
|
||||
message_route(action)
|
||||
end
|
||||
when :private_messages_group, :private_messages_group_archive
|
||||
define_method("#{action}") do
|
||||
group = Group.find_by("LOWER(name) = ?", params[:group_name].downcase)
|
||||
raise Discourse::NotFound if !group
|
||||
raise Discourse::NotFound unless guardian.can_see_group_messages?(group)
|
||||
|
||||
message_route(action)
|
||||
end
|
||||
else
|
||||
define_method("#{action}") do
|
||||
message_route(action)
|
||||
end
|
||||
define_method action do
|
||||
message_route(action)
|
||||
end
|
||||
end
|
||||
|
||||
def message_route(action)
|
||||
target_user = fetch_user_from_params({ include_inactive: current_user.try(:staff?) }, [:user_stat, :user_option])
|
||||
|
||||
case action
|
||||
when :private_messages_tag
|
||||
raise Discourse::NotFound if !guardian.can_tag_pms?
|
||||
when :private_messages_warnings
|
||||
guardian.ensure_can_see_warnings!(target_user)
|
||||
when :private_messages_group, :private_messages_group_archive
|
||||
group = Group.find_by("LOWER(name) = ?", params[:group_name].downcase)
|
||||
raise Discourse::NotFound if !group
|
||||
raise Discourse::NotFound unless guardian.can_see_group_messages?(group)
|
||||
else
|
||||
guardian.ensure_can_see_private_messages!(target_user.id)
|
||||
end
|
||||
|
||||
list_opts = build_topic_list_options
|
||||
list = generate_list_for(action.to_s, target_user, list_opts)
|
||||
url_prefix = "topics"
|
||||
|
@ -187,11 +179,19 @@ class ListController < ApplicationController
|
|||
private_messages
|
||||
private_messages_sent
|
||||
private_messages_unread
|
||||
private_messages_new
|
||||
private_messages_archive
|
||||
private_messages_group
|
||||
private_messages_group_new
|
||||
private_messages_group_unread
|
||||
private_messages_group_archive
|
||||
private_messages_tag
|
||||
private_messages_warnings
|
||||
private_messages_all
|
||||
private_messages_all_sent
|
||||
private_messages_all_unread
|
||||
private_messages_all_new
|
||||
private_messages_all_archive
|
||||
private_messages_tag
|
||||
}.each do |action|
|
||||
generate_message_route(action)
|
||||
end
|
||||
|
|
|
@ -136,16 +136,16 @@ class Tag < ActiveRecord::Base
|
|||
WHERE topic_tags.topic_id IN (
|
||||
SELECT topic_id
|
||||
FROM topic_allowed_users
|
||||
WHERE user_id = #{user_id}
|
||||
WHERE user_id = #{user_id.to_i}
|
||||
UNION
|
||||
SELECT tg.topic_id
|
||||
FROM topic_allowed_groups tg
|
||||
JOIN group_users gu ON gu.user_id = #{user_id}
|
||||
JOIN group_users gu ON gu.user_id = #{user_id.to_i}
|
||||
AND gu.group_id = tg.group_id
|
||||
)
|
||||
GROUP BY tags.name
|
||||
ORDER BY count DESC
|
||||
LIMIT #{limit}
|
||||
LIMIT #{limit.to_i}
|
||||
SQL
|
||||
end
|
||||
|
||||
|
|
|
@ -545,8 +545,9 @@ class TopicTrackingState
|
|||
group_user_ids = group.users.pluck(:id)
|
||||
next if group_user_ids.blank?
|
||||
group_channels = []
|
||||
group_channels << "/private-messages/group/#{group.name.downcase}"
|
||||
group_channels << "#{group_channels.first}/archive" if group_archive
|
||||
channel_prefix = "/private-messages/group/#{group.name.downcase}"
|
||||
group_channels << "#{channel_prefix}/inbox"
|
||||
group_channels << "#{channel_prefix}/archive" if group_archive
|
||||
group_channels.each { |channel| channels[channel] = group_user_ids }
|
||||
end
|
||||
|
||||
|
|
|
@ -1172,9 +1172,13 @@ en:
|
|||
rejected_posts: "rejected posts"
|
||||
|
||||
messages:
|
||||
all: "All"
|
||||
all: "all inboxes"
|
||||
inbox: "Inbox"
|
||||
personal: "Personal"
|
||||
latest: "Latest"
|
||||
sent: "Sent"
|
||||
unread: "Unread"
|
||||
new: "New"
|
||||
archive: "Archive"
|
||||
groups: "My Groups"
|
||||
move_to_inbox: "Move to Inbox"
|
||||
|
|
|
@ -447,9 +447,10 @@ Discourse::Application.routes.draw do
|
|||
get "#{root_path}/:username/private-messages/:filter" => "user_actions#private_messages", constraints: { username: RouteFormat.username }
|
||||
get "#{root_path}/:username/messages" => "user_actions#private_messages", constraints: { username: RouteFormat.username }
|
||||
get "#{root_path}/:username/messages/:filter" => "user_actions#private_messages", constraints: { username: RouteFormat.username }
|
||||
get "#{root_path}/:username/messages/personal" => "user_actions#private_messages", constraints: { username: RouteFormat.username }
|
||||
get "#{root_path}/:username/messages/personal/:filter" => "user_actions#private_messages", constraints: { username: RouteFormat.username }
|
||||
get "#{root_path}/:username/messages/group/:group_name" => "user_actions#private_messages", constraints: { username: RouteFormat.username, group_name: RouteFormat.username }
|
||||
get "#{root_path}/:username/messages/group/:group_name/archive" => "user_actions#private_messages", constraints: { username: RouteFormat.username, group_name: RouteFormat.username }
|
||||
get "#{root_path}/:username/messages/tags/:tag_id" => "user_actions#private_messages", constraints: StaffConstraint.new
|
||||
get "#{root_path}/:username/messages/group/:group_name/:filter" => "user_actions#private_messages", constraints: { username: RouteFormat.username, group_name: RouteFormat.username }
|
||||
get "#{root_path}/:username.json" => "users#show", constraints: { username: RouteFormat.username }, defaults: { format: :json }
|
||||
get({ "#{root_path}/:username" => "users#show", constraints: { username: RouteFormat.username } }.merge(index == 1 ? { as: 'user' } : {}))
|
||||
put "#{root_path}/:username" => "users#update", constraints: { username: RouteFormat.username }, defaults: { format: :json }
|
||||
|
@ -764,17 +765,25 @@ Discourse::Application.routes.draw do
|
|||
|
||||
scope "/topics", username: RouteFormat.username do
|
||||
get "created-by/:username" => "list#topics_by", as: "topics_by", defaults: { format: :json }
|
||||
get "private-messages-all/:username" => "list#private_messages_all", as: "topics_private_messages_all", defaults: { format: :json }
|
||||
get "private-messages-all-sent/:username" => "list#private_messages_all_sent", as: "topics_private_messages_all_sent", defaults: { format: :json }
|
||||
get "private-messages-all-new/:username" => "list#private_messages_all_new", as: "topics_private_messages_all_new", defaults: { format: :json }
|
||||
get "private-messages-all-unread/:username" => "list#private_messages_all_unread", as: "topics_private_messages_all_unread", defaults: { format: :json }
|
||||
get "private-messages-all-archive/:username" => "list#private_messages_all_archive", as: "topics_private_messages_all_archive", defaults: { format: :json }
|
||||
get "private-messages/:username" => "list#private_messages", as: "topics_private_messages", defaults: { format: :json }
|
||||
get "private-messages-sent/:username" => "list#private_messages_sent", as: "topics_private_messages_sent", defaults: { format: :json }
|
||||
get "private-messages-archive/:username" => "list#private_messages_archive", as: "topics_private_messages_archive", defaults: { format: :json }
|
||||
get "private-messages-unread/:username" => "list#private_messages_unread", as: "topics_private_messages_unread", defaults: { format: :json }
|
||||
get "private-messages-tags/:username/:tag_id.json" => "list#private_messages_tag", as: "topics_private_messages_tag", defaults: { format: :json }
|
||||
get "private-messages-new/:username" => "list#private_messages_new", as: "topics_private_messages_new", defaults: { format: :json }
|
||||
get "private-messages-warnings/:username" => "list#private_messages_warnings", as: "topics_private_messages_warnings", defaults: { format: :json }
|
||||
get "groups/:group_name" => "list#group_topics", as: "group_topics", group_name: RouteFormat.username
|
||||
|
||||
scope "/private-messages-group/:username", group_name: RouteFormat.username do
|
||||
get ":group_name.json" => "list#private_messages_group", as: "topics_private_messages_group"
|
||||
get ":group_name/archive.json" => "list#private_messages_group_archive", as: "topics_private_messages_group_archive"
|
||||
get ":group_name/new.json" => "list#private_messages_group_new", as: "topics_private_messages_group_new"
|
||||
get ":group_name/unread.json" => "list#private_messages_group_unread", as: "topics_private_messages_group_unread"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#
|
||||
|
||||
class TopicQuery
|
||||
include PrivateMessageLists
|
||||
|
||||
PG_MAX_INT ||= 2147483647
|
||||
DEFAULT_PER_PAGE_COUNT ||= 30
|
||||
|
||||
|
@ -293,12 +295,6 @@ class TopicQuery
|
|||
end
|
||||
end
|
||||
|
||||
def not_archived(list, user)
|
||||
list.joins("LEFT JOIN user_archived_messages um
|
||||
ON um.user_id = #{user.id.to_i} AND um.topic_id = topics.id")
|
||||
.where('um.user_id IS NULL')
|
||||
end
|
||||
|
||||
def list_group_topics(group)
|
||||
list = default_results.where("
|
||||
topics.user_id IN (
|
||||
|
@ -309,79 +305,6 @@ class TopicQuery
|
|||
create_list(:group_topics, {}, list)
|
||||
end
|
||||
|
||||
def list_private_messages(user)
|
||||
list = private_messages_for(user, :user)
|
||||
|
||||
list = not_archived(list, user)
|
||||
.where('NOT (topics.participant_count = 1 AND topics.user_id = ? AND topics.moderator_posts_count = 0)', user.id)
|
||||
|
||||
create_list(:private_messages, {}, list)
|
||||
end
|
||||
|
||||
def list_private_messages_archive(user)
|
||||
list = private_messages_for(user, :user)
|
||||
list = list.joins(:user_archived_messages).where('user_archived_messages.user_id = ?', user.id)
|
||||
create_list(:private_messages, {}, list)
|
||||
end
|
||||
|
||||
def list_private_messages_sent(user)
|
||||
list = private_messages_for(user, :user)
|
||||
list = list.where('EXISTS (
|
||||
SELECT 1 FROM posts
|
||||
WHERE posts.topic_id = topics.id AND
|
||||
posts.user_id = ?
|
||||
)', user.id)
|
||||
list = not_archived(list, user)
|
||||
create_list(:private_messages, {}, list)
|
||||
end
|
||||
|
||||
def list_private_messages_unread(user)
|
||||
list = private_messages_for(user, :user)
|
||||
|
||||
list = TopicQuery.unread_filter(
|
||||
list,
|
||||
staff: user.staff?
|
||||
)
|
||||
|
||||
first_unread_pm_at = UserStat.where(user_id: user.id).pluck_first(:first_unread_pm_at)
|
||||
list = list.where("topics.updated_at >= ?", first_unread_pm_at) if first_unread_pm_at
|
||||
create_list(:private_messages, {}, list)
|
||||
end
|
||||
|
||||
def list_private_messages_group(user)
|
||||
list = private_messages_for(user, :group)
|
||||
group = Group.where('name ilike ?', @options[:group_name]).select(:id, :publish_read_state).first
|
||||
publish_read_state = !!group&.publish_read_state
|
||||
list = list.joins("LEFT JOIN group_archived_messages gm ON gm.topic_id = topics.id AND
|
||||
gm.group_id = #{group&.id&.to_i}")
|
||||
list = list.where("gm.id IS NULL")
|
||||
list = append_read_state(list, group) if publish_read_state
|
||||
create_list(:private_messages, { publish_read_state: publish_read_state }, list)
|
||||
end
|
||||
|
||||
def list_private_messages_group_archive(user)
|
||||
list = private_messages_for(user, :group)
|
||||
group_id = Group.where('name ilike ?', @options[:group_name]).pluck_first(:id)
|
||||
list = list.joins("JOIN group_archived_messages gm ON gm.topic_id = topics.id AND
|
||||
gm.group_id = #{group_id.to_i}")
|
||||
create_list(:private_messages, {}, list)
|
||||
end
|
||||
|
||||
def list_private_messages_tag(user)
|
||||
list = private_messages_for(user, :all)
|
||||
list = list.joins("JOIN topic_tags tt ON tt.topic_id = topics.id
|
||||
JOIN tags t ON t.id = tt.tag_id AND t.name = '#{@options[:tags][0]}'")
|
||||
create_list(:private_messages, {}, list)
|
||||
end
|
||||
|
||||
def list_private_messages_warnings(user)
|
||||
list = private_messages_for(user, :user)
|
||||
list = list.where('topics.subtype = ?', TopicSubtype.moderator_warning)
|
||||
# Exclude official warnings that the user created, instead of received
|
||||
list = list.where('topics.user_id <> ?', user.id)
|
||||
create_list(:private_messages, {}, list)
|
||||
end
|
||||
|
||||
def list_category_topic_ids(category)
|
||||
query = default_results(category: category.id)
|
||||
pinned_ids = query.where('topics.pinned_at IS NOT NULL AND topics.category_id = ?', category.id).limit(nil).order('pinned_at DESC').pluck(:id)
|
||||
|
@ -590,50 +513,6 @@ class TopicQuery
|
|||
DEFAULT_PER_PAGE_COUNT
|
||||
end
|
||||
|
||||
def private_messages_for(user, type)
|
||||
options = @options
|
||||
options.reverse_merge!(per_page: per_page_setting)
|
||||
|
||||
result = Topic.includes(:allowed_users)
|
||||
result = result.includes(:tags) if SiteSetting.tagging_enabled
|
||||
|
||||
if type == :group
|
||||
result = result.joins(
|
||||
"INNER JOIN topic_allowed_groups tag ON tag.topic_id = topics.id AND tag.group_id IN (SELECT id FROM groups WHERE LOWER(name) = '#{PG::Connection.escape_string(@options[:group_name].downcase)}')"
|
||||
)
|
||||
|
||||
unless user.admin?
|
||||
result = result.joins("INNER JOIN group_users gu ON gu.group_id = tag.group_id AND gu.user_id = #{user.id.to_i}")
|
||||
end
|
||||
elsif type == :user
|
||||
result = result.where("topics.id IN (SELECT topic_id FROM topic_allowed_users WHERE user_id = #{user.id.to_i})")
|
||||
elsif type == :all
|
||||
result = result.where("topics.id IN (
|
||||
SELECT topic_id
|
||||
FROM topic_allowed_users
|
||||
WHERE user_id = #{user.id.to_i}
|
||||
UNION ALL
|
||||
SELECT topic_id FROM topic_allowed_groups
|
||||
WHERE group_id IN (
|
||||
SELECT group_id FROM group_users WHERE user_id = #{user.id.to_i}
|
||||
)
|
||||
)")
|
||||
end
|
||||
|
||||
result = result.joins("LEFT OUTER JOIN topic_users AS tu ON (topics.id = tu.topic_id AND tu.user_id = #{user.id.to_i})")
|
||||
.order("topics.bumped_at DESC")
|
||||
.private_messages
|
||||
|
||||
result = result.limit(options[:per_page]) unless options[:limit] == false
|
||||
result = result.visible if options[:visible] || @user.nil? || @user.regular?
|
||||
|
||||
if options[:page]
|
||||
offset = options[:page].to_i * options[:per_page]
|
||||
result = result.offset(offset) if offset > 0
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
def apply_shared_drafts(result, category_id, options)
|
||||
|
||||
# PERF: avoid any penalty if there are no shared drafts enabled
|
||||
|
@ -955,7 +834,7 @@ class TopicQuery
|
|||
list
|
||||
end
|
||||
|
||||
def remove_muted_tags(list, user, opts = nil)
|
||||
def remove_muted_tags(list, user, opts = {})
|
||||
if !SiteSetting.tagging_enabled || SiteSetting.remove_muted_tags_from_latest == 'never'
|
||||
return list
|
||||
end
|
||||
|
@ -1149,18 +1028,4 @@ class TopicQuery
|
|||
|
||||
result.order('topics.bumped_at DESC')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def append_read_state(list, group)
|
||||
group_id = group&.id
|
||||
return list if group_id.nil?
|
||||
|
||||
selected_values = list.select_values.empty? ? ['topics.*'] : list.select_values
|
||||
selected_values << "COALESCE(tg.last_read_post_number, 0) AS last_read_post_number"
|
||||
|
||||
list
|
||||
.joins("LEFT OUTER JOIN topic_groups tg ON topics.id = tg.topic_id AND tg.group_id = #{group_id}")
|
||||
.select(*selected_values)
|
||||
end
|
||||
end
|
||||
|
|
256
lib/topic_query/private_message_lists.rb
Normal file
256
lib/topic_query/private_message_lists.rb
Normal file
|
@ -0,0 +1,256 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class TopicQuery
|
||||
module PrivateMessageLists
|
||||
def list_private_messages_all(user)
|
||||
list = private_messages_for(user, :all)
|
||||
list = filter_archived(list, user, archived: false)
|
||||
create_list(:private_messages, {}, list)
|
||||
end
|
||||
|
||||
def list_private_messages_all_sent(user)
|
||||
list = private_messages_for(user, :all)
|
||||
|
||||
list = list.where(<<~SQL, user.id)
|
||||
EXISTS (
|
||||
SELECT 1 FROM posts
|
||||
WHERE posts.topic_id = topics.id AND posts.user_id = ?
|
||||
)
|
||||
SQL
|
||||
|
||||
list = filter_archived(list, user, archived: false)
|
||||
create_list(:private_messages, {}, list)
|
||||
end
|
||||
|
||||
def list_private_messages_all_archive(user)
|
||||
list = private_messages_for(user, :all)
|
||||
list = filter_archived(list, user, archived: true)
|
||||
create_list(:private_messages, {}, list)
|
||||
end
|
||||
|
||||
def list_private_messages_all_new(user)
|
||||
list_private_messages_new(user, :all)
|
||||
end
|
||||
|
||||
def list_private_messages_all_unread(user)
|
||||
list_private_messages_unread(user, :all)
|
||||
end
|
||||
|
||||
def list_private_messages(user)
|
||||
list = private_messages_for(user, :user)
|
||||
list = not_archived(list, user)
|
||||
create_list(:private_messages, {}, list)
|
||||
end
|
||||
|
||||
def list_private_messages_archive(user)
|
||||
list = private_messages_for(user, :user)
|
||||
list = list.joins(:user_archived_messages).where('user_archived_messages.user_id = ?', user.id)
|
||||
create_list(:private_messages, {}, list)
|
||||
end
|
||||
|
||||
def list_private_messages_sent(user)
|
||||
list = private_messages_for(user, :user)
|
||||
|
||||
list = list.where(<<~SQL, user.id)
|
||||
EXISTS (
|
||||
SELECT 1 FROM posts
|
||||
WHERE posts.topic_id = topics.id AND posts.user_id = ?
|
||||
)
|
||||
SQL
|
||||
|
||||
list = not_archived(list, user)
|
||||
create_list(:private_messages, {}, list)
|
||||
end
|
||||
|
||||
def list_private_messages_new(user, type = :user)
|
||||
list = TopicQuery.new_filter(
|
||||
private_messages_for(user, type),
|
||||
treat_as_new_topic_start_date: user.user_option.treat_as_new_topic_start_date
|
||||
)
|
||||
|
||||
list = remove_muted_tags(list, user)
|
||||
|
||||
create_list(:private_messages, {}, list)
|
||||
end
|
||||
|
||||
def list_private_messages_unread(user, type = :user)
|
||||
list = TopicQuery.unread_filter(
|
||||
private_messages_for(user, type),
|
||||
staff: user.staff?
|
||||
)
|
||||
|
||||
first_unread_pm_at = UserStat
|
||||
.where(user_id: user.id)
|
||||
.pluck_first(:first_unread_pm_at)
|
||||
|
||||
if first_unread_pm_at
|
||||
list = list.where("topics.updated_at >= ?", first_unread_pm_at)
|
||||
end
|
||||
|
||||
create_list(:private_messages, {}, list)
|
||||
end
|
||||
|
||||
def list_private_messages_group(user)
|
||||
list = private_messages_for(user, :group)
|
||||
|
||||
list = list.joins(<<~SQL)
|
||||
LEFT JOIN group_archived_messages gm
|
||||
ON gm.topic_id = topics.id AND gm.group_id = #{group.id.to_i}
|
||||
SQL
|
||||
|
||||
list = list.where("gm.id IS NULL")
|
||||
publish_read_state = !!group.publish_read_state
|
||||
list = append_read_state(list, group) if publish_read_state
|
||||
create_list(:private_messages, { publish_read_state: publish_read_state }, list)
|
||||
end
|
||||
|
||||
def list_private_messages_group_archive(user)
|
||||
list = private_messages_for(user, :group)
|
||||
|
||||
list = list.joins(<<~SQL)
|
||||
INNER JOIN group_archived_messages gm
|
||||
ON gm.topic_id = topics.id AND gm.group_id = #{group.id.to_i}
|
||||
SQL
|
||||
|
||||
publish_read_state = !!group.publish_read_state
|
||||
list = append_read_state(list, group) if publish_read_state
|
||||
create_list(:private_messages, { publish_read_state: publish_read_state }, list)
|
||||
end
|
||||
|
||||
def list_private_messages_group_new(user)
|
||||
list = TopicQuery.new_filter(
|
||||
private_messages_for(user, :group),
|
||||
treat_as_new_topic_start_date: user.user_option.treat_as_new_topic_start_date
|
||||
)
|
||||
|
||||
publish_read_state = !!group.publish_read_state
|
||||
list = append_read_state(list, group) if publish_read_state
|
||||
create_list(:private_messages, { publish_read_state: publish_read_state }, list)
|
||||
end
|
||||
|
||||
def list_private_messages_group_unread(user)
|
||||
list = TopicQuery.unread_filter(
|
||||
private_messages_for(user, :group),
|
||||
staff: user.staff?
|
||||
)
|
||||
|
||||
first_unread_pm_at = UserStat
|
||||
.where(user_id: user.id)
|
||||
.pluck_first(:first_unread_pm_at)
|
||||
|
||||
if first_unread_pm_at
|
||||
list = list.where("topics.updated_at >= ?", first_unread_pm_at)
|
||||
end
|
||||
|
||||
publish_read_state = !!group.publish_read_state
|
||||
list = append_read_state(list, group) if publish_read_state
|
||||
create_list(:private_messages, { publish_read_state: publish_read_state }, list)
|
||||
end
|
||||
|
||||
def list_private_messages_warnings(user)
|
||||
list = private_messages_for(user, :user)
|
||||
list = list.where('topics.subtype = ?', TopicSubtype.moderator_warning)
|
||||
# Exclude official warnings that the user created, instead of received
|
||||
list = list.where('topics.user_id <> ?', user.id)
|
||||
create_list(:private_messages, {}, list)
|
||||
end
|
||||
|
||||
def private_messages_for(user, type)
|
||||
options = @options
|
||||
options.reverse_merge!(per_page: per_page_setting)
|
||||
|
||||
result = Topic.includes(:allowed_users)
|
||||
result = result.includes(:tags) if SiteSetting.tagging_enabled
|
||||
|
||||
if type == :group
|
||||
result = result.joins(
|
||||
"INNER JOIN topic_allowed_groups tag ON tag.topic_id = topics.id AND tag.group_id IN (SELECT id FROM groups WHERE LOWER(name) = '#{PG::Connection.escape_string(@options[:group_name].downcase)}')"
|
||||
)
|
||||
|
||||
unless user.admin?
|
||||
result = result.joins("INNER JOIN group_users gu ON gu.group_id = tag.group_id AND gu.user_id = #{user.id.to_i}")
|
||||
end
|
||||
elsif type == :user
|
||||
result = result.where("topics.id IN (SELECT topic_id FROM topic_allowed_users WHERE user_id = #{user.id.to_i})")
|
||||
elsif type == :all
|
||||
result = result.where("topics.id IN (
|
||||
SELECT topic_id
|
||||
FROM topic_allowed_users
|
||||
WHERE user_id = #{user.id.to_i}
|
||||
UNION ALL
|
||||
SELECT topic_id FROM topic_allowed_groups
|
||||
WHERE group_id IN (
|
||||
SELECT group_id FROM group_users WHERE user_id = #{user.id.to_i}
|
||||
)
|
||||
)")
|
||||
end
|
||||
|
||||
result = result.joins("LEFT OUTER JOIN topic_users AS tu ON (topics.id = tu.topic_id AND tu.user_id = #{user.id.to_i})")
|
||||
.order("topics.bumped_at DESC")
|
||||
.private_messages
|
||||
|
||||
result = result.limit(options[:per_page]) unless options[:limit] == false
|
||||
result = result.visible if options[:visible] || @user.nil? || @user.regular?
|
||||
|
||||
if options[:page]
|
||||
offset = options[:page].to_i * options[:per_page]
|
||||
result = result.offset(offset) if offset > 0
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
def list_private_messages_tag(user)
|
||||
list = private_messages_for(user, :all)
|
||||
list = list.joins("JOIN topic_tags tt ON tt.topic_id = topics.id
|
||||
JOIN tags t ON t.id = tt.tag_id AND t.name = '#{@options[:tags][0]}'")
|
||||
create_list(:private_messages, {}, list)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def append_read_state(list, group)
|
||||
group_id = group.id
|
||||
return list if group_id.nil?
|
||||
|
||||
selected_values = list.select_values.empty? ? ['topics.*'] : list.select_values
|
||||
selected_values << "COALESCE(tg.last_read_post_number, 0) AS last_read_post_number"
|
||||
|
||||
list
|
||||
.joins("LEFT OUTER JOIN topic_groups tg ON topics.id = tg.topic_id AND tg.group_id = #{group_id}")
|
||||
.select(*selected_values)
|
||||
end
|
||||
|
||||
def filter_archived(list, user, archived: true)
|
||||
list = list.joins(<<~SQL)
|
||||
LEFT JOIN group_archived_messages gm ON gm.topic_id = topics.id
|
||||
LEFT JOIN user_archived_messages um
|
||||
ON um.user_id = #{user.id.to_i}
|
||||
AND um.topic_id = topics.id
|
||||
SQL
|
||||
|
||||
list =
|
||||
if archived
|
||||
list.where("um.user_id IS NOT NULL OR gm.topic_id IS NOT NULL")
|
||||
else
|
||||
list.where("um.user_id IS NULL AND gm.topic_id IS NULL")
|
||||
end
|
||||
|
||||
list
|
||||
end
|
||||
|
||||
def not_archived(list, user)
|
||||
list.joins("LEFT JOIN user_archived_messages um
|
||||
ON um.user_id = #{user.id.to_i} AND um.topic_id = topics.id")
|
||||
.where('um.user_id IS NULL')
|
||||
end
|
||||
|
||||
def group
|
||||
@group ||= begin
|
||||
Group
|
||||
.where('name ilike ?', @options[:group_name])
|
||||
.select(:id, :publish_read_state)
|
||||
.first
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1067,7 +1067,6 @@ describe TopicQuery do
|
|||
|
||||
expect(TopicQuery.new(user, tags: [tag.name]).list_private_messages_tag(user).topics).to eq([private_message])
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1193,75 +1192,6 @@ describe TopicQuery do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#list_private_messages_group' do
|
||||
fab!(:group) { Fabricate(:group) }
|
||||
|
||||
let!(:group_message) do
|
||||
Fabricate(:private_message_topic,
|
||||
allowed_groups: [group],
|
||||
topic_allowed_users: [
|
||||
Fabricate.build(:topic_allowed_user, user: Fabricate(:user)),
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
before do
|
||||
group.add(creator)
|
||||
end
|
||||
|
||||
it 'should return the right list for a group user' do
|
||||
topics = TopicQuery.new(nil, group_name: group.name)
|
||||
.list_private_messages_group(creator)
|
||||
.topics
|
||||
|
||||
expect(topics).to contain_exactly(group_message)
|
||||
end
|
||||
|
||||
it 'should return the right list for an admin not part of the group' do
|
||||
group.update!(name: group.name.capitalize)
|
||||
|
||||
topics = TopicQuery.new(nil, group_name: group.name.upcase)
|
||||
.list_private_messages_group(Fabricate(:admin))
|
||||
.topics
|
||||
|
||||
expect(topics).to contain_exactly(group_message)
|
||||
end
|
||||
|
||||
it "should not allow a moderator not part of the group to view the group's messages" do
|
||||
topics = TopicQuery.new(nil, group_name: group.name)
|
||||
.list_private_messages_group(Fabricate(:moderator))
|
||||
.topics
|
||||
|
||||
expect(topics).to eq([])
|
||||
end
|
||||
|
||||
it "should not allow a user not part of the group to view the group's messages" do
|
||||
topics = TopicQuery.new(nil, group_name: group.name)
|
||||
.list_private_messages_group(Fabricate(:user))
|
||||
.topics
|
||||
|
||||
expect(topics).to eq([])
|
||||
end
|
||||
|
||||
context "Calculating minimum unread count for a topic" do
|
||||
before { group.update!(publish_read_state: true) }
|
||||
|
||||
let(:listed_message) do
|
||||
TopicQuery.new(nil, group_name: group.name)
|
||||
.list_private_messages_group(creator)
|
||||
.topics.first
|
||||
end
|
||||
|
||||
it 'returns the last read post number' do
|
||||
topic_group = TopicGroup.create!(
|
||||
topic: group_message, group: group, last_read_post_number: 10
|
||||
)
|
||||
|
||||
expect(listed_message.last_read_post_number).to eq(topic_group.last_read_post_number)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "shared drafts" do
|
||||
fab!(:category) { Fabricate(:category_with_definition) }
|
||||
fab!(:shared_drafts_category) { Fabricate(:category_with_definition) }
|
||||
|
@ -1349,16 +1279,4 @@ describe TopicQuery do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#list_private_messages' do
|
||||
it "includes topics with moderator posts" do
|
||||
private_message_topic = Fabricate(:private_message_post, user: user).topic
|
||||
|
||||
expect(TopicQuery.new(user).list_private_messages(user).topics).to be_empty
|
||||
|
||||
private_message_topic.add_moderator_post(admin, "Thank you for your flag")
|
||||
|
||||
expect(TopicQuery.new(user).list_private_messages(user).topics).to eq([private_message_topic])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
305
spec/lib/topic_query/private_message_lists_spec.rb
Normal file
305
spec/lib/topic_query/private_message_lists_spec.rb
Normal file
|
@ -0,0 +1,305 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe TopicQuery::PrivateMessageLists do
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
fab!(:user_2) { Fabricate(:user) }
|
||||
|
||||
fab!(:group) do
|
||||
Fabricate(:group, messageable_level: Group::ALIAS_LEVELS[:everyone]).tap do |g|
|
||||
g.add(user_2)
|
||||
end
|
||||
end
|
||||
|
||||
fab!(:group_message) do
|
||||
create_post(
|
||||
user: user,
|
||||
target_group_names: [group.name],
|
||||
archetype: Archetype.private_message
|
||||
).topic
|
||||
end
|
||||
|
||||
fab!(:private_message) do
|
||||
create_post(
|
||||
user: user,
|
||||
target_usernames: [user_2.username],
|
||||
archetype: Archetype.private_message
|
||||
).topic
|
||||
end
|
||||
|
||||
describe '#list_private_messages_all' do
|
||||
it 'returns a list of all private messages that a user has access to' do
|
||||
topics = TopicQuery.new(nil).list_private_messages_all(user).topics
|
||||
|
||||
expect(topics).to contain_exactly(group_message, private_message)
|
||||
end
|
||||
|
||||
it 'does not include user or group archived messages' do
|
||||
UserArchivedMessage.archive!(user.id, group_message)
|
||||
UserArchivedMessage.archive!(user.id, private_message)
|
||||
|
||||
topics = TopicQuery.new(nil).list_private_messages_all(user).topics
|
||||
|
||||
expect(topics).to eq([])
|
||||
|
||||
GroupArchivedMessage.archive!(user_2.id, group_message)
|
||||
|
||||
topics = TopicQuery.new(nil).list_private_messages_all(user_2).topics
|
||||
|
||||
expect(topics).to contain_exactly(private_message)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#list_private_messages_all_sent' do
|
||||
it 'returns a list of all private messages that a user has sent' do
|
||||
topics = TopicQuery.new(nil).list_private_messages_all_sent(user_2).topics
|
||||
|
||||
expect(topics).to eq([])
|
||||
|
||||
create_post(user: user_2, topic: private_message)
|
||||
|
||||
topics = TopicQuery.new(nil).list_private_messages_all_sent(user_2).topics
|
||||
|
||||
expect(topics).to contain_exactly(private_message)
|
||||
|
||||
create_post(user: user_2, topic: group_message)
|
||||
|
||||
topics = TopicQuery.new(nil).list_private_messages_all_sent(user_2).topics
|
||||
|
||||
expect(topics).to contain_exactly(private_message, group_message)
|
||||
end
|
||||
|
||||
it 'does not include user or group archived messages' do
|
||||
create_post(user: user_2, topic: private_message)
|
||||
create_post(user: user_2, topic: group_message)
|
||||
|
||||
UserArchivedMessage.archive!(user_2.id, private_message)
|
||||
GroupArchivedMessage.archive!(user_2.id, group_message)
|
||||
|
||||
topics = TopicQuery.new(nil).list_private_messages_all_sent(user_2).topics
|
||||
|
||||
expect(topics).to eq([])
|
||||
end
|
||||
end
|
||||
|
||||
describe '#list_private_messages_all_archive' do
|
||||
it 'returns a list of all private messages that has been archived' do
|
||||
UserArchivedMessage.archive!(user_2.id, private_message)
|
||||
GroupArchivedMessage.archive!(user_2.id, group_message)
|
||||
|
||||
topics = TopicQuery.new(nil).list_private_messages_all_archive(user_2).topics
|
||||
|
||||
expect(topics).to contain_exactly(private_message, group_message)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#list_private_messages_all_new' do
|
||||
it 'returns a list of new private messages' do
|
||||
topics = TopicQuery.new(nil).list_private_messages_all_new(user_2).topics
|
||||
|
||||
expect(topics).to contain_exactly(private_message, group_message)
|
||||
|
||||
TopicUser.find_by(user: user_2, topic: group_message).update!(
|
||||
last_read_post_number: 1
|
||||
)
|
||||
|
||||
topics = TopicQuery.new(nil).list_private_messages_all_new(user_2).topics
|
||||
|
||||
expect(topics).to contain_exactly(private_message)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#list_private_messages_all_unread' do
|
||||
it 'returns a list of unread private messages' do
|
||||
topics = TopicQuery.new(nil).list_private_messages_all_unread(user_2).topics
|
||||
|
||||
expect(topics).to eq([])
|
||||
|
||||
TopicUser.find_by(user: user_2, topic: group_message).update!(
|
||||
last_read_post_number: 1
|
||||
)
|
||||
|
||||
create_post(user: user, topic: group_message)
|
||||
|
||||
topics = TopicQuery.new(nil).list_private_messages_all_unread(user_2).topics
|
||||
|
||||
expect(topics).to contain_exactly(group_message)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#list_private_messages' do
|
||||
it 'returns a list of all private messages that a user has access to' do
|
||||
topics = TopicQuery.new(nil).list_private_messages(user_2).topics
|
||||
|
||||
expect(topics).to contain_exactly(private_message)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#list_private_messages_group' do
|
||||
it 'should return the right list for a group user' do
|
||||
group.add(user_2)
|
||||
|
||||
topics = TopicQuery.new(nil, group_name: group.name)
|
||||
.list_private_messages_group(user_2)
|
||||
.topics
|
||||
|
||||
expect(topics).to contain_exactly(group_message)
|
||||
end
|
||||
|
||||
it 'should return the right list for an admin not part of the group' do
|
||||
group.update!(name: group.name.capitalize)
|
||||
|
||||
topics = TopicQuery.new(nil, group_name: group.name.upcase)
|
||||
.list_private_messages_group(Fabricate(:admin))
|
||||
.topics
|
||||
|
||||
expect(topics).to contain_exactly(group_message)
|
||||
end
|
||||
|
||||
it "should not allow a moderator not part of the group to view the group's messages" do
|
||||
topics = TopicQuery.new(nil, group_name: group.name)
|
||||
.list_private_messages_group(Fabricate(:moderator))
|
||||
.topics
|
||||
|
||||
expect(topics).to eq([])
|
||||
end
|
||||
|
||||
it "should not allow a user not part of the group to view the group's messages" do
|
||||
topics = TopicQuery.new(nil, group_name: group.name)
|
||||
.list_private_messages_group(Fabricate(:user))
|
||||
.topics
|
||||
|
||||
expect(topics).to eq([])
|
||||
end
|
||||
|
||||
context "Calculating minimum unread count for a topic" do
|
||||
before do
|
||||
group.update!(publish_read_state: true)
|
||||
group.add(user)
|
||||
end
|
||||
|
||||
let(:listed_message) do
|
||||
TopicQuery.new(nil, group_name: group.name)
|
||||
.list_private_messages_group(user)
|
||||
.topics.first
|
||||
end
|
||||
|
||||
it 'returns the last read post number' do
|
||||
topic_group = TopicGroup.create!(
|
||||
topic: group_message, group: group, last_read_post_number: 10
|
||||
)
|
||||
|
||||
expect(listed_message.last_read_post_number).to eq(topic_group.last_read_post_number)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#list_private_messages_group_new' do
|
||||
it 'returns a list of new private messages for a group that user is a part of' do
|
||||
topics = TopicQuery.new(nil, group_name: group.name)
|
||||
.list_private_messages_group_new(user_2)
|
||||
.topics
|
||||
|
||||
expect(topics).to contain_exactly(group_message)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#list_private_messages_group_unread' do
|
||||
it 'returns a list of unread private messages for a group that user is a part of' do
|
||||
topics = TopicQuery.new(nil, group_name: group.name)
|
||||
.list_private_messages_group_unread(user_2)
|
||||
.topics
|
||||
|
||||
expect(topics).to eq([])
|
||||
|
||||
TopicUser.find_by(user: user_2, topic: group_message).update!(
|
||||
last_read_post_number: 1
|
||||
)
|
||||
|
||||
create_post(user: user, topic: group_message)
|
||||
|
||||
topics = TopicQuery.new(nil, group_name: group.name)
|
||||
.list_private_messages_group_unread(user_2)
|
||||
.topics
|
||||
|
||||
expect(topics).to contain_exactly(group_message)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#list_private_messages_unread' do
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
fab!(:user_2) { Fabricate(:user) }
|
||||
|
||||
fab!(:pm) do
|
||||
create_post(
|
||||
user: user,
|
||||
target_usernames: [user_2.username],
|
||||
archetype: Archetype.private_message
|
||||
).topic
|
||||
end
|
||||
|
||||
fab!(:pm_2) do
|
||||
create_post(
|
||||
user: user,
|
||||
target_usernames: [user_2.username],
|
||||
archetype: Archetype.private_message
|
||||
).topic
|
||||
end
|
||||
|
||||
fab!(:pm_3) do
|
||||
create_post(
|
||||
user: user,
|
||||
target_usernames: [user_2.username],
|
||||
archetype: Archetype.private_message
|
||||
).topic
|
||||
end
|
||||
|
||||
it 'returns a list of private messages with unread posts that user is at least tracking' do
|
||||
freeze_time 1.minute.from_now do
|
||||
create_post(user: user_2, topic_id: pm.id)
|
||||
create_post(user: user_2, topic_id: pm_3.id)
|
||||
end
|
||||
|
||||
TopicUser.find_by(user: user, topic: pm_3).update!(
|
||||
notification_level: TopicUser.notification_levels[:regular]
|
||||
)
|
||||
|
||||
expect(TopicQuery.new(user).list_private_messages_unread(user).topics)
|
||||
.to contain_exactly(pm)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#list_private_messages_new' do
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
fab!(:user_2) { Fabricate(:user) }
|
||||
|
||||
fab!(:pm) do
|
||||
create_post(
|
||||
user: user,
|
||||
target_usernames: [user_2.username],
|
||||
archetype: Archetype.private_message
|
||||
).topic
|
||||
end
|
||||
|
||||
it 'returns a list of new private messages' do
|
||||
expect(TopicQuery.new(user_2).list_private_messages_new(user_2).topics)
|
||||
.to contain_exactly(pm)
|
||||
end
|
||||
|
||||
it 'returns a list of new private messages accounting for muted tags' do
|
||||
tag = Fabricate(:tag)
|
||||
|
||||
pm.tags << tag
|
||||
|
||||
TagUser.create!(
|
||||
tag: tag,
|
||||
user: user_2,
|
||||
notification_level: TopicUser.notification_levels[:muted]
|
||||
)
|
||||
|
||||
expect(TopicQuery.new(user_2).list_private_messages_new(user_2).topics)
|
||||
.to eq([])
|
||||
end
|
||||
end
|
||||
end
|
|
@ -205,8 +205,8 @@ describe TopicTrackingState do
|
|||
|
||||
expect(messages.map(&:channel)).to contain_exactly(
|
||||
'/private-messages/inbox',
|
||||
"/private-messages/group/#{group1.name}",
|
||||
"/private-messages/group/#{group2.name}"
|
||||
"/private-messages/group/#{group1.name}/inbox",
|
||||
"/private-messages/group/#{group2.name}/inbox"
|
||||
)
|
||||
|
||||
message = messages.find do |m|
|
||||
|
@ -218,7 +218,7 @@ describe TopicTrackingState do
|
|||
|
||||
[group1, group2].each do |group|
|
||||
message = messages.find do |m|
|
||||
m.channel == "/private-messages/group/#{group.name}"
|
||||
m.channel == "/private-messages/group/#{group.name}/inbox"
|
||||
end
|
||||
|
||||
expect(message.data["topic_id"]).to eq(private_message_topic.id)
|
||||
|
@ -237,9 +237,9 @@ describe TopicTrackingState do
|
|||
|
||||
expect(messages.map(&:channel)).to contain_exactly(
|
||||
'/private-messages/inbox',
|
||||
"/private-messages/group/#{group1.name}",
|
||||
"/private-messages/group/#{group1.name}/inbox",
|
||||
"/private-messages/group/#{group1.name}/archive",
|
||||
"/private-messages/group/#{group2.name}",
|
||||
"/private-messages/group/#{group2.name}/inbox",
|
||||
"/private-messages/group/#{group2.name}/archive",
|
||||
)
|
||||
|
||||
|
@ -249,11 +249,9 @@ describe TopicTrackingState do
|
|||
expect(message.user_ids).to eq(private_message_topic.allowed_users.map(&:id))
|
||||
|
||||
[group1, group2].each do |group|
|
||||
group_channel = "/private-messages/group/#{group.name}"
|
||||
|
||||
[
|
||||
group_channel,
|
||||
"#{group_channel}/archive"
|
||||
"/private-messages/group/#{group.name}/inbox",
|
||||
"/private-messages/group/#{group.name}/archive"
|
||||
].each do |channel|
|
||||
message = messages.find { |m| m.channel == channel }
|
||||
expect(message.data["topic_id"]).to eq(private_message_topic.id)
|
||||
|
@ -291,7 +289,7 @@ describe TopicTrackingState do
|
|||
expected_channels = [
|
||||
'/private-messages/inbox',
|
||||
'/private-messages/sent',
|
||||
"/private-messages/group/#{group.name}"
|
||||
"/private-messages/group/#{group.name}/inbox"
|
||||
]
|
||||
|
||||
expect(messages.map(&:channel)).to contain_exactly(*expected_channels)
|
||||
|
|
|
@ -473,7 +473,7 @@ describe TagsController do
|
|||
it "can't see pm tags" do
|
||||
get "/tags/personal_messages/#{regular_user.username}.json"
|
||||
|
||||
expect(response).not_to be_successful
|
||||
expect(response.status).to eq(403)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -485,7 +485,7 @@ describe TagsController do
|
|||
it "can't see pm tags for regular user" do
|
||||
get "/tags/personal_messages/#{regular_user.username}.json"
|
||||
|
||||
expect(response).not_to be_successful
|
||||
expect(response.status).to eq(404)
|
||||
end
|
||||
|
||||
it "can see their own pm tags" do
|
||||
|
|
Loading…
Reference in New Issue
Block a user