From 3b8819f0ab2442779c5b461e55504dbe55ab7f66 Mon Sep 17 00:00:00 2001 From: Sam Saffron Date: Fri, 31 May 2019 15:43:17 +1000 Subject: [PATCH] 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. --- .../components/topic-footer-buttons.js.es6 | 2 ++ .../controllers/preferences/interface.js.es6 | 1 + .../discourse/controllers/topic.js.es6 | 21 +++++++++++++++++ .../initializers/topic-footer-buttons.js.es6 | 15 ++++++++++++ .../javascripts/discourse/models/user.js.es6 | 2 ++ .../templates/preferences/interface.hbs | 1 + .../javascripts/discourse/templates/topic.hbs | 1 + app/models/user_option.rb | 2 ++ app/serializers/current_user_serializer.rb | 5 ++++ app/serializers/user_option_serializer.rb | 1 + app/services/user_updater.rb | 1 + config/locales/client.en.yml | 4 ++++ config/locales/server.en.yml | 1 + config/site_settings.yml | 1 + ...044744_add_enable_defer_to_user_options.rb | 7 ++++++ spec/models/user_option_spec.rb | 23 +++++++++++++++---- 16 files changed, 83 insertions(+), 5 deletions(-) create mode 100644 db/migrate/20190531044744_add_enable_defer_to_user_options.rb diff --git a/app/assets/javascripts/discourse/components/topic-footer-buttons.js.es6 b/app/assets/javascripts/discourse/components/topic-footer-buttons.js.es6 index 00872269000..0c487e73530 100644 --- a/app/assets/javascripts/discourse/components/topic-footer-buttons.js.es6 +++ b/app/assets/javascripts/discourse/components/topic-footer-buttons.js.es6 @@ -32,6 +32,8 @@ export default Ember.Component.extend({ canInviteTo: Ember.computed.alias("topic.details.can_invite_to"), + canDefer: Ember.computed.alias("currentUser.enable_defer"), + inviteDisabled: Ember.computed.or( "topic.archived", "topic.closed", diff --git a/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6 b/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6 index 915db2d1654..072c42c3b63 100644 --- a/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6 +++ b/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6 @@ -31,6 +31,7 @@ export default Ember.Controller.extend(PreferencesTabController, { "external_links_in_new_tab", "dynamic_favicon", "enable_quoting", + "enable_defer", "automatically_unpin_topics", "allow_private_messages", "homepage_id", diff --git a/app/assets/javascripts/discourse/controllers/topic.js.es6 b/app/assets/javascripts/discourse/controllers/topic.js.es6 index 1ec3b6cf30a..157969600f8 100644 --- a/app/assets/javascripts/discourse/controllers/topic.js.es6 +++ b/app/assets/javascripts/discourse/controllers/topic.js.es6 @@ -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() { const postStream = this.get("model.postStream"); let firstPost = postStream.get("posts.firstObject"); diff --git a/app/assets/javascripts/discourse/initializers/topic-footer-buttons.js.es6 b/app/assets/javascripts/discourse/initializers/topic-footer-buttons.js.es6 index ccb2e2e9d1f..fce251ff0f1 100644 --- a/app/assets/javascripts/discourse/initializers/topic-footer-buttons.js.es6 +++ b/app/assets/javascripts/discourse/initializers/topic-footer-buttons.js.es6 @@ -148,5 +148,20 @@ export default { 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; + } + }); } }; diff --git a/app/assets/javascripts/discourse/models/user.js.es6 b/app/assets/javascripts/discourse/models/user.js.es6 index 90b47dc083f..b9064d13f62 100644 --- a/app/assets/javascripts/discourse/models/user.js.es6 +++ b/app/assets/javascripts/discourse/models/user.js.es6 @@ -271,6 +271,7 @@ const User = RestModel.extend({ "email_previous_replies", "dynamic_favicon", "enable_quoting", + "enable_defer", "automatically_unpin_topics", "digest_after_minutes", "new_topic_duration_minutes", @@ -338,6 +339,7 @@ const User = RestModel.extend({ const userProps = Ember.getProperties( this.user_option, "enable_quoting", + "enable_defer", "external_links_in_new_tab", "dynamic_favicon" ); diff --git a/app/assets/javascripts/discourse/templates/preferences/interface.hbs b/app/assets/javascripts/discourse/templates/preferences/interface.hbs index e1192d127d8..854c51162d0 100644 --- a/app/assets/javascripts/discourse/templates/preferences/interface.hbs +++ b/app/assets/javascripts/discourse/templates/preferences/interface.hbs @@ -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.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}} {{preference-checkbox labelKey="user.automatically_unpin_topics" checked=model.user_option.automatically_unpin_topics}} {{/if}} diff --git a/app/assets/javascripts/discourse/templates/topic.hbs b/app/assets/javascripts/discourse/templates/topic.hbs index b47f7935cc2..f58cc7fd56c 100644 --- a/app/assets/javascripts/discourse/templates/topic.hbs +++ b/app/assets/javascripts/discourse/templates/topic.hbs @@ -301,6 +301,7 @@ showFlagTopic=(route-action "showFlagTopic") toggleArchiveMessage=(action "toggleArchiveMessage") editFirstPost=(action "editFirstPost") + deferTopic=(action "deferTopic") replyToPost=(action "replyToPost")}} {{else}}