FEATURE: add support for defer topic functionality
This feature allows end users to "defer" topics by marking them unread The functionality is default disabled. This also introduces the new site setting default_other_enable_defer: to enable this by default on new user accounts.
This commit is contained in:
parent
5c526e5abb
commit
3b8819f0ab
|
@ -32,6 +32,8 @@ export default Ember.Component.extend({
|
||||||
|
|
||||||
canInviteTo: Ember.computed.alias("topic.details.can_invite_to"),
|
canInviteTo: Ember.computed.alias("topic.details.can_invite_to"),
|
||||||
|
|
||||||
|
canDefer: Ember.computed.alias("currentUser.enable_defer"),
|
||||||
|
|
||||||
inviteDisabled: Ember.computed.or(
|
inviteDisabled: Ember.computed.or(
|
||||||
"topic.archived",
|
"topic.archived",
|
||||||
"topic.closed",
|
"topic.closed",
|
||||||
|
|
|
@ -31,6 +31,7 @@ export default Ember.Controller.extend(PreferencesTabController, {
|
||||||
"external_links_in_new_tab",
|
"external_links_in_new_tab",
|
||||||
"dynamic_favicon",
|
"dynamic_favicon",
|
||||||
"enable_quoting",
|
"enable_quoting",
|
||||||
|
"enable_defer",
|
||||||
"automatically_unpin_topics",
|
"automatically_unpin_topics",
|
||||||
"allow_private_messages",
|
"allow_private_messages",
|
||||||
"homepage_id",
|
"homepage_id",
|
||||||
|
|
|
@ -405,6 +405,27 @@ export default Ember.Controller.extend(bufferedProperty("model"), {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
deferTopic() {
|
||||||
|
const screenTrack = Discourse.__container__.lookup("screen-track:main");
|
||||||
|
const currentUser = this.currentUser;
|
||||||
|
const topic = this.model;
|
||||||
|
|
||||||
|
screenTrack.reset();
|
||||||
|
screenTrack.stop();
|
||||||
|
const goToPath = topic.get("isPrivateMessage")
|
||||||
|
? currentUser.pmPath(topic)
|
||||||
|
: "/";
|
||||||
|
ajax("/t/" + topic.get("id") + "/timings.json?last=1", { type: "DELETE" })
|
||||||
|
.then(() => {
|
||||||
|
const highestSeenByTopic = Discourse.Session.currentProp(
|
||||||
|
"highestSeenByTopic"
|
||||||
|
);
|
||||||
|
highestSeenByTopic[topic.get("id")] = null;
|
||||||
|
DiscourseURL.routeTo(goToPath);
|
||||||
|
})
|
||||||
|
.catch(popupAjaxError);
|
||||||
|
},
|
||||||
|
|
||||||
editFirstPost() {
|
editFirstPost() {
|
||||||
const postStream = this.get("model.postStream");
|
const postStream = this.get("model.postStream");
|
||||||
let firstPost = postStream.get("posts.firstObject");
|
let firstPost = postStream.get("posts.firstObject");
|
||||||
|
|
|
@ -148,5 +148,20 @@ export default {
|
||||||
return this.showEditOnFooter;
|
return this.showEditOnFooter;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
registerTopicFooterButton({
|
||||||
|
id: "defer",
|
||||||
|
icon: "circle",
|
||||||
|
priority: 300,
|
||||||
|
label: "topic.defer.title",
|
||||||
|
title: "topic.defer.help",
|
||||||
|
action: "deferTopic",
|
||||||
|
displayed() {
|
||||||
|
return this.canDefer;
|
||||||
|
},
|
||||||
|
dropdown() {
|
||||||
|
return this.site.mobileView;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -271,6 +271,7 @@ const User = RestModel.extend({
|
||||||
"email_previous_replies",
|
"email_previous_replies",
|
||||||
"dynamic_favicon",
|
"dynamic_favicon",
|
||||||
"enable_quoting",
|
"enable_quoting",
|
||||||
|
"enable_defer",
|
||||||
"automatically_unpin_topics",
|
"automatically_unpin_topics",
|
||||||
"digest_after_minutes",
|
"digest_after_minutes",
|
||||||
"new_topic_duration_minutes",
|
"new_topic_duration_minutes",
|
||||||
|
@ -338,6 +339,7 @@ const User = RestModel.extend({
|
||||||
const userProps = Ember.getProperties(
|
const userProps = Ember.getProperties(
|
||||||
this.user_option,
|
this.user_option,
|
||||||
"enable_quoting",
|
"enable_quoting",
|
||||||
|
"enable_defer",
|
||||||
"external_links_in_new_tab",
|
"external_links_in_new_tab",
|
||||||
"dynamic_favicon"
|
"dynamic_favicon"
|
||||||
);
|
);
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
|
|
||||||
{{preference-checkbox labelKey="user.external_links_in_new_tab" checked=model.user_option.external_links_in_new_tab}}
|
{{preference-checkbox labelKey="user.external_links_in_new_tab" checked=model.user_option.external_links_in_new_tab}}
|
||||||
{{preference-checkbox labelKey="user.enable_quoting" checked=model.user_option.enable_quoting}}
|
{{preference-checkbox labelKey="user.enable_quoting" checked=model.user_option.enable_quoting}}
|
||||||
|
{{preference-checkbox labelKey="user.enable_defer" checked=model.user_option.enable_defer}}
|
||||||
{{#if siteSettings.automatically_unpin_topics}}
|
{{#if siteSettings.automatically_unpin_topics}}
|
||||||
{{preference-checkbox labelKey="user.automatically_unpin_topics" checked=model.user_option.automatically_unpin_topics}}
|
{{preference-checkbox labelKey="user.automatically_unpin_topics" checked=model.user_option.automatically_unpin_topics}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
@ -301,6 +301,7 @@
|
||||||
showFlagTopic=(route-action "showFlagTopic")
|
showFlagTopic=(route-action "showFlagTopic")
|
||||||
toggleArchiveMessage=(action "toggleArchiveMessage")
|
toggleArchiveMessage=(action "toggleArchiveMessage")
|
||||||
editFirstPost=(action "editFirstPost")
|
editFirstPost=(action "editFirstPost")
|
||||||
|
deferTopic=(action "deferTopic")
|
||||||
replyToPost=(action "replyToPost")}}
|
replyToPost=(action "replyToPost")}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<div id="topic-footer-buttons">
|
<div id="topic-footer-buttons">
|
||||||
|
|
|
@ -53,6 +53,7 @@ class UserOption < ActiveRecord::Base
|
||||||
self.email_in_reply_to = SiteSetting.default_email_in_reply_to
|
self.email_in_reply_to = SiteSetting.default_email_in_reply_to
|
||||||
|
|
||||||
self.enable_quoting = SiteSetting.default_other_enable_quoting
|
self.enable_quoting = SiteSetting.default_other_enable_quoting
|
||||||
|
self.enable_defer = SiteSetting.default_other_enable_defer
|
||||||
self.external_links_in_new_tab = SiteSetting.default_other_external_links_in_new_tab
|
self.external_links_in_new_tab = SiteSetting.default_other_external_links_in_new_tab
|
||||||
self.dynamic_favicon = SiteSetting.default_other_dynamic_favicon
|
self.dynamic_favicon = SiteSetting.default_other_dynamic_favicon
|
||||||
|
|
||||||
|
@ -222,6 +223,7 @@ end
|
||||||
# email_level :integer default(1), not null
|
# email_level :integer default(1), not null
|
||||||
# email_messages_level :integer default(0), not null
|
# email_messages_level :integer default(0), not null
|
||||||
# title_count_mode_key :integer default(0), not null
|
# title_count_mode_key :integer default(0), not null
|
||||||
|
# enable_defer :boolean default(FALSE), not null
|
||||||
#
|
#
|
||||||
# Indexes
|
# Indexes
|
||||||
#
|
#
|
||||||
|
|
|
@ -16,6 +16,7 @@ class CurrentUserSerializer < BasicUserSerializer
|
||||||
:reply_count,
|
:reply_count,
|
||||||
:topic_count,
|
:topic_count,
|
||||||
:enable_quoting,
|
:enable_quoting,
|
||||||
|
:enable_defer,
|
||||||
:external_links_in_new_tab,
|
:external_links_in_new_tab,
|
||||||
:dynamic_favicon,
|
:dynamic_favicon,
|
||||||
:trust_level,
|
:trust_level,
|
||||||
|
@ -79,6 +80,10 @@ class CurrentUserSerializer < BasicUserSerializer
|
||||||
object.user_option.enable_quoting
|
object.user_option.enable_quoting
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def enable_defer
|
||||||
|
object.user_option.enable_defer
|
||||||
|
end
|
||||||
|
|
||||||
def external_links_in_new_tab
|
def external_links_in_new_tab
|
||||||
object.user_option.external_links_in_new_tab
|
object.user_option.external_links_in_new_tab
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,6 +10,7 @@ class UserOptionSerializer < ApplicationSerializer
|
||||||
:external_links_in_new_tab,
|
:external_links_in_new_tab,
|
||||||
:dynamic_favicon,
|
:dynamic_favicon,
|
||||||
:enable_quoting,
|
:enable_quoting,
|
||||||
|
:enable_defer,
|
||||||
:digest_after_minutes,
|
:digest_after_minutes,
|
||||||
:automatically_unpin_topics,
|
:automatically_unpin_topics,
|
||||||
:auto_track_topics_after_msecs,
|
:auto_track_topics_after_msecs,
|
||||||
|
|
|
@ -24,6 +24,7 @@ class UserUpdater
|
||||||
:email_messages_level,
|
:email_messages_level,
|
||||||
:external_links_in_new_tab,
|
:external_links_in_new_tab,
|
||||||
:enable_quoting,
|
:enable_quoting,
|
||||||
|
:enable_defer,
|
||||||
:dynamic_favicon,
|
:dynamic_favicon,
|
||||||
:automatically_unpin_topics,
|
:automatically_unpin_topics,
|
||||||
:digest_after_minutes,
|
:digest_after_minutes,
|
||||||
|
|
|
@ -803,6 +803,7 @@ en:
|
||||||
allow_private_messages: "Allow other users to send me personal messages"
|
allow_private_messages: "Allow other users to send me personal messages"
|
||||||
external_links_in_new_tab: "Open all external links in a new tab"
|
external_links_in_new_tab: "Open all external links in a new tab"
|
||||||
enable_quoting: "Enable quote reply for highlighted text"
|
enable_quoting: "Enable quote reply for highlighted text"
|
||||||
|
enable_defer: "Enable defer to mark topics unread"
|
||||||
change: "change"
|
change: "change"
|
||||||
moderator: "{{user}} is a moderator"
|
moderator: "{{user}} is a moderator"
|
||||||
admin: "{{user}} is an admin"
|
admin: "{{user}} is an admin"
|
||||||
|
@ -1880,6 +1881,9 @@ en:
|
||||||
edit_message:
|
edit_message:
|
||||||
help: "Edit first post of the message"
|
help: "Edit first post of the message"
|
||||||
title: "Edit Message"
|
title: "Edit Message"
|
||||||
|
defer:
|
||||||
|
help: "Mark as unread"
|
||||||
|
title: "Defer"
|
||||||
list: "Topics"
|
list: "Topics"
|
||||||
new: "new topic"
|
new: "new topic"
|
||||||
unread: "unread"
|
unread: "unread"
|
||||||
|
|
|
@ -1978,6 +1978,7 @@ en:
|
||||||
default_other_notification_level_when_replying: "Global default notification level when the user replies to a topic."
|
default_other_notification_level_when_replying: "Global default notification level when the user replies to a topic."
|
||||||
default_other_external_links_in_new_tab: "Open external links in a new tab by default."
|
default_other_external_links_in_new_tab: "Open external links in a new tab by default."
|
||||||
default_other_enable_quoting: "Enable quote reply for highlighted text by default."
|
default_other_enable_quoting: "Enable quote reply for highlighted text by default."
|
||||||
|
default_other_enable_defer: "Enable defer topic functionality by default."
|
||||||
default_other_dynamic_favicon: "Show new/updated topic count on browser icon by default."
|
default_other_dynamic_favicon: "Show new/updated topic count on browser icon by default."
|
||||||
|
|
||||||
default_other_like_notification_frequency: "Notify users on likes by default"
|
default_other_like_notification_frequency: "Notify users on likes by default"
|
||||||
|
|
|
@ -1939,6 +1939,7 @@ user_preferences:
|
||||||
default: 2
|
default: 2
|
||||||
default_other_external_links_in_new_tab: false
|
default_other_external_links_in_new_tab: false
|
||||||
default_other_enable_quoting: true
|
default_other_enable_quoting: true
|
||||||
|
default_other_enable_defer: false
|
||||||
default_other_dynamic_favicon: false
|
default_other_dynamic_favicon: false
|
||||||
default_other_like_notification_frequency:
|
default_other_like_notification_frequency:
|
||||||
enum: "LikeNotificationFrequencySiteSetting"
|
enum: "LikeNotificationFrequencySiteSetting"
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AddEnableDeferToUserOptions < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
add_column :user_options, :enable_defer, :boolean, default: false, null: false
|
||||||
|
end
|
||||||
|
end
|
|
@ -18,7 +18,7 @@ describe UserOption do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "should_be_redirected_to_top" do
|
describe "defaults" do
|
||||||
fab!(:user) { Fabricate(:user) }
|
fab!(:user) { Fabricate(:user) }
|
||||||
|
|
||||||
it "should be redirected to top when there is a reason to" do
|
it "should be redirected to top when there is a reason to" do
|
||||||
|
@ -30,16 +30,29 @@ describe UserOption do
|
||||||
user.user_option.expects(:redirected_to_top).returns(nil)
|
user.user_option.expects(:redirected_to_top).returns(nil)
|
||||||
expect(user.user_option.should_be_redirected_to_top).to eq(false)
|
expect(user.user_option.should_be_redirected_to_top).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
describe "defaults" do
|
|
||||||
fab!(:user) { Fabricate(:user) }
|
|
||||||
|
|
||||||
it "should not hide the profile and presence by default" do
|
it "should not hide the profile and presence by default" do
|
||||||
expect(user.user_option.hide_profile_and_presence).to eq(false)
|
expect(user.user_option.hide_profile_and_presence).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "site settings" do
|
||||||
|
it "should apply defaults from site settings" do
|
||||||
|
|
||||||
|
SiteSetting.default_other_enable_quoting = false
|
||||||
|
SiteSetting.default_other_enable_defer = true
|
||||||
|
SiteSetting.default_other_external_links_in_new_tab = true
|
||||||
|
SiteSetting.default_other_dynamic_favicon = true
|
||||||
|
|
||||||
|
user = Fabricate(:user)
|
||||||
|
|
||||||
|
expect(user.user_option.enable_quoting).to eq(false)
|
||||||
|
expect(user.user_option.enable_defer).to eq(true)
|
||||||
|
expect(user.user_option.external_links_in_new_tab).to eq(true)
|
||||||
|
expect(user.user_option.dynamic_favicon).to eq(true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "#mailing_list_mode" do
|
describe "#mailing_list_mode" do
|
||||||
fab!(:forum_user) { Fabricate(:user) }
|
fab!(:forum_user) { Fabricate(:user) }
|
||||||
fab!(:mailing_list_user) { Fabricate(:user) }
|
fab!(:mailing_list_user) { Fabricate(:user) }
|
||||||
|
|
Loading…
Reference in New Issue