DEV: Include unread topics in New topic lists and link to it in sidebar (#20432)

This commit introduces a few experimental changes to the New topics list and "Everything" link in the sidebar:

1. Make the New topics list include unread topics
2. Make the Everything section in the sidebar link to the New topics list (`/new`)
3. Remove "unread" or "new" text next to the count and keep the count
4. The count is a sum of new and unread topics counts

All of these of changes are behind an off-by-default feature flag. I've not written extensive tests for these changes because they're highly experimental.

Internal topic: t/77234.
This commit is contained in:
Osama Sayegh 2023-02-27 15:11:01 +03:00 committed by GitHub
parent badd40090f
commit a509441148
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 70 additions and 12 deletions

View File

@ -150,7 +150,6 @@ const controllerOpts = {
hasTopics: gt("model.topics.length", 0),
allLoaded: empty("model.more_topics_url"),
latest: endWith("model.filter", "latest"),
new: endWith("model.filter", "new"),
top: endWith("model.filter", "top"),
yearly: equal("period", "yearly"),
quarterly: equal("period", "quarterly"),
@ -158,6 +157,11 @@ const controllerOpts = {
weekly: equal("period", "weekly"),
daily: equal("period", "daily"),
@discourseComputed("model.filter")
new(filter) {
return filter?.endsWith("new") && !this.currentUser?.new_new_view_enabled;
},
@discourseComputed("allLoaded", "model.topics.length")
footerMessage(allLoaded, topicsLength) {
if (!allLoaded) {

View File

@ -9,6 +9,7 @@ export default class EverythingSectionLink extends BaseSectionLink {
@tracked totalNew = 0;
@tracked hideCount =
this.currentUser?.sidebarListDestination !== UNREAD_LIST_DESTINATION;
linkToNew = !!this.currentUser?.new_new_view_enabled;
constructor() {
super(...arguments);
@ -26,7 +27,7 @@ export default class EverythingSectionLink extends BaseSectionLink {
this.totalUnread = this.topicTrackingState.countUnread();
if (this.totalUnread === 0) {
if (this.totalUnread === 0 || this.linkToNew) {
this.totalNew = this.topicTrackingState.countNew();
}
}
@ -48,10 +49,17 @@ export default class EverythingSectionLink extends BaseSectionLink {
}
get currentWhen() {
return "discovery.latest discovery.new discovery.unread discovery.top";
if (this.linkToNew) {
return "discovery.new";
} else {
return "discovery.latest discovery.new discovery.unread discovery.top";
}
}
get badgeText() {
if (this.linkToNew && this.#unreadAndNewCount > 0) {
return this.#unreadAndNewCount.toString();
}
if (this.hideCount) {
return;
}
@ -63,13 +71,15 @@ export default class EverythingSectionLink extends BaseSectionLink {
return I18n.t("sidebar.new_count", {
count: this.totalNew,
});
} else {
return;
}
}
get route() {
if (this.currentUser?.sidebarListDestination === UNREAD_LIST_DESTINATION) {
if (this.linkToNew) {
return "discovery.new";
} else if (
this.currentUser?.sidebarListDestination === UNREAD_LIST_DESTINATION
) {
if (this.totalUnread > 0) {
return "discovery.unread";
}
@ -93,8 +103,16 @@ export default class EverythingSectionLink extends BaseSectionLink {
}
get suffixValue() {
if (this.hideCount && (this.totalUnread || this.totalNew)) {
if (
this.hideCount &&
(this.totalUnread || this.totalNew) &&
!this.linkToNew
) {
return "circle";
}
}
get #unreadAndNewCount() {
return this.totalUnread + this.totalNew;
}
}

View File

@ -249,6 +249,10 @@ NavItem.reopenClass({
}
let items = args.siteSettings.top_menu.split("|");
const user = getOwner(this).lookup("service:current-user");
if (user?.new_new_view_enabled) {
items = items.reject((item) => item === "unread");
}
const filterType = (args.filterMode || "").split("/").pop();
if (!items.some((i) => filterType === i)) {

View File

@ -709,12 +709,21 @@ const TopicTrackingState = EmberObject.extend({
let categoryId = category ? get(category, "id") : null;
if (type === "new") {
return this.countNew({
let count = this.countNew({
categoryId,
tagId,
noSubcategories,
customFilterFn,
});
if (this.currentUser?.new_new_view_enabled) {
count += this.countUnread({
categoryId,
tagId,
noSubcategories,
customFilterFn,
});
}
return count;
} else if (type === "unread") {
return this.countUnread({
categoryId,
@ -790,8 +799,14 @@ const TopicTrackingState = EmberObject.extend({
// for a particular seen topic has not yet reached the server.
_fixDelayedServerState(list, filter) {
for (let index = list.topics.length - 1; index >= 0; index--) {
const state = this.findState(list.topics[index].id);
if (state && state.last_read_post_number > 0) {
const topic = list.topics[index];
const state = this.findState(topic.id);
if (
state &&
state.last_read_post_number > 0 &&
(topic.last_read_post_number === 0 ||
!this.currentUser?.new_new_view_enabled)
) {
if (filter === "new") {
list.topics.splice(index, 1);
} else {

View File

@ -1812,6 +1812,10 @@ class User < ActiveRecord::Base
!SiteSetting.legacy_navigation_menu? || SiteSetting.enable_new_notifications_menu
end
def new_new_view_enabled?
in_any_groups?(SiteSetting.experimental_new_new_view_groups_map)
end
protected
def badge_grant

View File

@ -69,7 +69,8 @@ class CurrentUserSerializer < BasicUserSerializer
:sidebar_category_ids,
:sidebar_list_destination,
:sidebar_sections,
:custom_sidebar_sections_enabled
:custom_sidebar_sections_enabled,
:new_new_view_enabled?
delegate :user_stat, to: :object, private: true
delegate :any_posts, :draft_count, :pending_posts_count, :read_faq?, to: :user_stat

View File

@ -2398,6 +2398,7 @@ en:
default_sidebar_tags: "Selected tags will be displayed under Sidebar's Tags section by default."
enable_new_notifications_menu: "Enables the new notifications menu for the legacy navigation menu."
enable_experimental_hashtag_autocomplete: "EXPERIMENTAL: Use the new #hashtag autocompletion system for categories and tags that renders the selected item differently and has improved search"
experimental_new_new_view_groups: "EXPERIMENTAL: Enable a new topics list that combines unread and new topics and make the \"Everything\" link in the sidebar link to it."
errors:
invalid_css_color: "Invalid color. Enter a color name or hex value."

View File

@ -2073,6 +2073,13 @@ developer:
client: true
default: false
hidden: true
experimental_new_new_view_groups:
client: true
type: group_list
list_type: compact
default: ""
allow_any: false
refresh: true
navigation:
navigation_menu:

View File

@ -267,7 +267,11 @@ class TopicQuery
end
def list_new
create_list(:new, { unordered: true }, new_results)
if @user&.new_new_view_enabled?
create_list(:new, { unordered: true }, new_and_unread_results)
else
create_list(:new, { unordered: true }, new_results)
end
end
def list_unread