diff --git a/app/assets/javascripts/discourse/controllers/topic.js.es6 b/app/assets/javascripts/discourse/controllers/topic.js.es6 index 2ab47ccc6..a2fb293ea 100644 --- a/app/assets/javascripts/discourse/controllers/topic.js.es6 +++ b/app/assets/javascripts/discourse/controllers/topic.js.es6 @@ -109,6 +109,14 @@ export default Ember.Controller.extend(SelectedPostsCount, BufferedContent, { this.deleteTopic(); }, + archiveMessage() { + this.get('model').archiveMessage(); + }, + + moveToInbox() { + this.get('model').moveToInbox(); + }, + // Post related methods replyToPost(post) { const composerController = this.get('controllers.composer'), diff --git a/app/assets/javascripts/discourse/models/topic.js.es6 b/app/assets/javascripts/discourse/models/topic.js.es6 index c7588f096..bbbd6886d 100644 --- a/app/assets/javascripts/discourse/models/topic.js.es6 +++ b/app/assets/javascripts/discourse/models/topic.js.es6 @@ -419,7 +419,27 @@ const Topic = RestModel.extend({ }.property('excerpt'), readLastPost: propertyEqual('last_read_post_number', 'highest_post_number'), - canClearPin: Em.computed.and('pinned', 'readLastPost') + canClearPin: Em.computed.and('pinned', 'readLastPost'), + + archiveMessage() { + this.set("archiving", true); + var promise = Discourse.ajax(`/t/${this.get('id')}/archive-message`, {type: 'PUT'}); + + promise.then(()=>this.set('message_archived', true)) + .finally(()=>this.set('archiving', false)); + + return promise; + }, + + moveToInbox() { + this.set("archiving", true); + var promise = Discourse.ajax(`/t/${this.get('id')}/move-to-inbox`, {type: 'PUT'}); + + promise.then(()=>this.set('message_archived', false)) + .finally(()=>this.set('archiving', false)); + + return promise; + } }); diff --git a/app/assets/javascripts/discourse/templates/topic.hbs b/app/assets/javascripts/discourse/templates/topic.hbs index ae02b7b9c..1b5b86afe 100644 --- a/app/assets/javascripts/discourse/templates/topic.hbs +++ b/app/assets/javascripts/discourse/templates/topic.hbs @@ -199,7 +199,9 @@ {{#if model.archived}} {{d-button action="toggleArchived" icon="folder" label="topic.actions.unarchive"}} {{else}} + {{#unless model.isPrivateMessage}} {{d-button action="toggleArchived" icon="folder" label="topic.actions.archive"}} + {{/unless}} {{/if}} diff --git a/app/assets/javascripts/discourse/views/archive-button.js.es6 b/app/assets/javascripts/discourse/views/archive-button.js.es6 new file mode 100644 index 000000000..39e046d10 --- /dev/null +++ b/app/assets/javascripts/discourse/views/archive-button.js.es6 @@ -0,0 +1,35 @@ +import StringBuffer from 'discourse/mixins/string-buffer'; + +export default Ember.View.extend(StringBuffer, { + tagName: 'button', + classNames: ['btn', 'standard'], + attributeBindings: ['title'], + archived: Em.computed.alias('controller.model.message_archived'), + archiving: Em.computed.alias('controller.model.archiving'), + rerenderTriggers: ['archived', 'archiving'], + + title: function() { + const key = this.get('archived') ? 'topic.move_to_inbox.help' : 'topic.archive_message.help'; + return I18n.t(key); + }.property('archived'), + + renderString: function(buffer) { + if (this.get('archived')){ + buffer.push(I18n.t('topic.move_to_inbox.title')); + } else { + buffer.push(""); + buffer.push(I18n.t('topic.archive_message.title')); + } + }, + + click: function() { + if (!this.get('archiving')) { + if (this.get('archived')) { + this.get('controller').send('moveToInbox'); + } else { + this.get('controller').send('archiveMessage'); + } + } + } +}); + diff --git a/app/assets/javascripts/discourse/views/topic-footer-main-buttons.js.es6 b/app/assets/javascripts/discourse/views/topic-footer-main-buttons.js.es6 index b35cfc9dd..bc63cd182 100644 --- a/app/assets/javascripts/discourse/views/topic-footer-main-buttons.js.es6 +++ b/app/assets/javascripts/discourse/views/topic-footer-main-buttons.js.es6 @@ -31,9 +31,14 @@ export default ContainerView.extend({ } } + if (topic.get('isPrivateMessage')) { + this.attachViewClass('archive-button'); + } + if (this.get('topic.details.can_create_post')) { this.attachViewClass('reply-button'); } + this.trigger('additionalButtons', this); } }); diff --git a/app/assets/stylesheets/desktop/user.scss b/app/assets/stylesheets/desktop/user.scss index fc9252ab7..56e196f73 100644 --- a/app/assets/stylesheets/desktop/user.scss +++ b/app/assets/stylesheets/desktop/user.scss @@ -667,10 +667,11 @@ li > a.active { color: $primary; + font-weight: bold; background-color: transparent; } li > a.active:after { - border-left-color: $primary; + border-left-color: none; } } diff --git a/app/controllers/topics_controller.rb b/app/controllers/topics_controller.rb index 1803f4b39..b049438b6 100644 --- a/app/controllers/topics_controller.rb +++ b/app/controllers/topics_controller.rb @@ -25,6 +25,8 @@ class TopicsController < ApplicationController :reset_new, :change_post_owners, :change_timestamps, + :archive_message, + :move_to_inbox, :bookmark] before_filter :consider_user_for_promotion, only: :show @@ -269,6 +271,40 @@ class TopicsController < ApplicationController render nothing: true end + def archive_message + toggle_archive_message(true) + end + + def move_to_inbox + toggle_archive_message(false) + end + + def toggle_archive_message(archive) + topic = Topic.find(params[:id].to_i) + group_ids = current_user.groups.pluck(:id) + if group_ids.present? + allowed_groups = topic.allowed_groups + .where('topic_allowed_groups.group_id IN (?)', group_ids).pluck(:id) + allowed_groups.each do |id| + GroupArchivedMessage.where(group_id: id, topic_id: topic.id).destroy_all + + if archive + GroupArchivedMessage.create!(group_id: id, topic_id: topic.id) + end + end + end + + if topic.allowed_users.include?(current_user) + UserArchivedMessage.where(user_id: current_user.id, topic_id: topic.id).destroy_all + + if archive + UserArchivedMessage.create!(user_id: current_user.id, topic_id: topic.id) + end + end + + render nothing: true + end + def bookmark topic = Topic.find(params[:topic_id].to_i) first_post = topic.ordered_posts.first diff --git a/app/models/topic.rb b/app/models/topic.rb index d2440a57c..5f470c509 100644 --- a/app/models/topic.rb +++ b/app/models/topic.rb @@ -904,6 +904,26 @@ class Topic < ActiveRecord::Base SiteSetting.embed_truncate? && has_topic_embed? end + def message_archived?(user) + return false unless user && user.id + + sql = < 0 + + end + TIME_TO_FIRST_RESPONSE_SQL ||= <<-SQL SELECT AVG(t.hours)::float AS "hours", t.created_at AS "date" FROM ( diff --git a/app/serializers/topic_view_serializer.rb b/app/serializers/topic_view_serializer.rb index a616c4a1b..866baa4d9 100644 --- a/app/serializers/topic_view_serializer.rb +++ b/app/serializers/topic_view_serializer.rb @@ -53,7 +53,8 @@ class TopicViewSerializer < ApplicationSerializer :expandable_first_post, :is_warning, :chunk_size, - :bookmarked + :bookmarked, + :message_archived # TODO: Split off into proper object / serializer def details @@ -141,6 +142,14 @@ class TopicViewSerializer < ApplicationSerializer object.draft_sequence end + def include_message_archived? + object.topic.private_message? + end + + def message_archived + object.topic.message_archived?(scope.user) + end + def deleted_by BasicUserSerializer.new(object.topic.deleted_by, root: false).as_json end diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 28c4ea7b3..629e4e11b 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -1094,6 +1094,12 @@ en: create: 'New Topic' create_long: 'Create a new Topic' private_message: 'Start a message' + archive_message: + help: 'Move message to your archive' + title: 'Archive' + move_to_inbox: + title: 'Move to Inbox' + help: 'Move message back to Inbox' list: 'Topics' new: 'new topic' unread: 'unread' diff --git a/config/routes.rb b/config/routes.rb index 0206708c4..638396dd3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -460,6 +460,8 @@ Discourse::Application.routes.draw do post "t" => "topics#create" put "t/:id" => "topics#update" delete "t/:id" => "topics#destroy" + put "t/:id/archive-message" => "topics#archive_message" + put "t/:id/move-to-inbox" => "topics#move_to_inbox" put "topics/bulk" put "topics/reset-new" => 'topics#reset_new' post "topics/timings"