FEATURE: allow users to archive messages from message page

This commit is contained in:
Sam 2015-12-30 13:26:21 +11:00
parent 6c9f646e34
commit a4587b18f5
11 changed files with 147 additions and 3 deletions

View file

@ -109,6 +109,14 @@ export default Ember.Controller.extend(SelectedPostsCount, BufferedContent, {
this.deleteTopic(); this.deleteTopic();
}, },
archiveMessage() {
this.get('model').archiveMessage();
},
moveToInbox() {
this.get('model').moveToInbox();
},
// Post related methods // Post related methods
replyToPost(post) { replyToPost(post) {
const composerController = this.get('controllers.composer'), const composerController = this.get('controllers.composer'),

View file

@ -419,7 +419,27 @@ const Topic = RestModel.extend({
}.property('excerpt'), }.property('excerpt'),
readLastPost: propertyEqual('last_read_post_number', 'highest_post_number'), 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;
}
}); });

View file

@ -199,7 +199,9 @@
{{#if model.archived}} {{#if model.archived}}
{{d-button action="toggleArchived" icon="folder" label="topic.actions.unarchive"}} {{d-button action="toggleArchived" icon="folder" label="topic.actions.unarchive"}}
{{else}} {{else}}
{{#unless model.isPrivateMessage}}
{{d-button action="toggleArchived" icon="folder" label="topic.actions.archive"}} {{d-button action="toggleArchived" icon="folder" label="topic.actions.archive"}}
{{/unless}}
{{/if}} {{/if}}
</li> </li>

View file

@ -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("<i class='fa fa-folder'></i>");
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');
}
}
}
});

View file

@ -31,9 +31,14 @@ export default ContainerView.extend({
} }
} }
if (topic.get('isPrivateMessage')) {
this.attachViewClass('archive-button');
}
if (this.get('topic.details.can_create_post')) { if (this.get('topic.details.can_create_post')) {
this.attachViewClass('reply-button'); this.attachViewClass('reply-button');
} }
this.trigger('additionalButtons', this); this.trigger('additionalButtons', this);
} }
}); });

View file

@ -667,10 +667,11 @@
li > a.active { li > a.active {
color: $primary; color: $primary;
font-weight: bold;
background-color: transparent; background-color: transparent;
} }
li > a.active:after { li > a.active:after {
border-left-color: $primary; border-left-color: none;
} }
} }

View file

@ -25,6 +25,8 @@ class TopicsController < ApplicationController
:reset_new, :reset_new,
:change_post_owners, :change_post_owners,
:change_timestamps, :change_timestamps,
:archive_message,
:move_to_inbox,
:bookmark] :bookmark]
before_filter :consider_user_for_promotion, only: :show before_filter :consider_user_for_promotion, only: :show
@ -269,6 +271,40 @@ class TopicsController < ApplicationController
render nothing: true render nothing: true
end 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 def bookmark
topic = Topic.find(params[:topic_id].to_i) topic = Topic.find(params[:topic_id].to_i)
first_post = topic.ordered_posts.first first_post = topic.ordered_posts.first

View file

@ -904,6 +904,26 @@ class Topic < ActiveRecord::Base
SiteSetting.embed_truncate? && has_topic_embed? SiteSetting.embed_truncate? && has_topic_embed?
end end
def message_archived?(user)
return false unless user && user.id
sql = <<SQL
SELECT 1 FROM topic_allowed_groups tg
JOIN group_archived_messages gm ON gm.topic_id = tg.topic_id AND gm.group_id = tg.group_id
WHERE tg.group_id IN (SELECT g.id FROM group_users g WHERE g.user_id = :user_id)
AND tg.topic_id = :topic_id
UNION ALL
SELECT 1 FROM topic_allowed_users tu
JOIN user_archived_messages um ON um.user_id = tu.user_id AND um.topic_id = tu.topic_id
WHERE tu.user_id = :user_id AND tu.topic_id = :topic_id
SQL
User.exec_sql(sql, user_id: user.id, topic_id: id).to_a.length > 0
end
TIME_TO_FIRST_RESPONSE_SQL ||= <<-SQL TIME_TO_FIRST_RESPONSE_SQL ||= <<-SQL
SELECT AVG(t.hours)::float AS "hours", t.created_at AS "date" SELECT AVG(t.hours)::float AS "hours", t.created_at AS "date"
FROM ( FROM (

View file

@ -53,7 +53,8 @@ class TopicViewSerializer < ApplicationSerializer
:expandable_first_post, :expandable_first_post,
:is_warning, :is_warning,
:chunk_size, :chunk_size,
:bookmarked :bookmarked,
:message_archived
# TODO: Split off into proper object / serializer # TODO: Split off into proper object / serializer
def details def details
@ -141,6 +142,14 @@ class TopicViewSerializer < ApplicationSerializer
object.draft_sequence object.draft_sequence
end end
def include_message_archived?
object.topic.private_message?
end
def message_archived
object.topic.message_archived?(scope.user)
end
def deleted_by def deleted_by
BasicUserSerializer.new(object.topic.deleted_by, root: false).as_json BasicUserSerializer.new(object.topic.deleted_by, root: false).as_json
end end

View file

@ -1094,6 +1094,12 @@ en:
create: 'New Topic' create: 'New Topic'
create_long: 'Create a new Topic' create_long: 'Create a new Topic'
private_message: 'Start a message' 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' list: 'Topics'
new: 'new topic' new: 'new topic'
unread: 'unread' unread: 'unread'

View file

@ -460,6 +460,8 @@ Discourse::Application.routes.draw do
post "t" => "topics#create" post "t" => "topics#create"
put "t/:id" => "topics#update" put "t/:id" => "topics#update"
delete "t/:id" => "topics#destroy" 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/bulk"
put "topics/reset-new" => 'topics#reset_new' put "topics/reset-new" => 'topics#reset_new'
post "topics/timings" post "topics/timings"