mirror of https://github.com/zulip/zulip.git
Add a checkbox that propagates topic edits to subsequent messages.
Trac #1348 (imported from commit 28e2a8cb3ecda5ec50d17501f4ccbd8644212065)
This commit is contained in:
parent
07d692758e
commit
19a835e7d5
|
@ -14,6 +14,10 @@ exports.save = function (row) {
|
|||
var new_topic = row.find(".message_edit_topic").val();
|
||||
if (new_topic !== message.subject && new_topic.trim() !== "") {
|
||||
request.subject = new_topic;
|
||||
|
||||
if (row.find(".message_edit_topic_propagate>input").is(":checked")) {
|
||||
request.propagate_subject = true;
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -734,23 +734,33 @@ function update_messages(events) {
|
|||
}
|
||||
|
||||
if (event.subject !== undefined) {
|
||||
// Remove the recent subjects entry for the old subject;
|
||||
// must be called before we update msg.subject
|
||||
process_message_for_recent_subjects(msg, true);
|
||||
// Update the unread counts; again, this must be called
|
||||
// before we update msg.subject
|
||||
unread.update_unread_subjects(msg, event);
|
||||
// A topic edit may affect multiple messages, listed in
|
||||
// event.message_ids. event.message_id is still the first message
|
||||
// where the user initiated the edit.
|
||||
_.each(event.message_ids, function (id) {
|
||||
var msg = all_msg_list.get(id);
|
||||
if (msg === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
msg.subject = event.subject;
|
||||
msg.subject_links = event.subject_links;
|
||||
if (msg.subject === compose.empty_subject_placeholder()) {
|
||||
msg.empty_subject = true;
|
||||
} else {
|
||||
msg.empty_subject = false;
|
||||
}
|
||||
// Add the recent subjects entry for the new subject; must
|
||||
// be called after we update msg.subject
|
||||
process_message_for_recent_subjects(msg);
|
||||
// Remove the recent subjects entry for the old subject;
|
||||
// must be called before we update msg.subject
|
||||
process_message_for_recent_subjects(msg, true);
|
||||
// Update the unread counts; again, this must be called
|
||||
// before we update msg.subject
|
||||
unread.update_unread_subjects(msg, event);
|
||||
|
||||
msg.subject = event.subject;
|
||||
msg.subject_links = event.subject_links;
|
||||
if (msg.subject === compose.empty_subject_placeholder()) {
|
||||
msg.empty_subject = true;
|
||||
} else {
|
||||
msg.empty_subject = false;
|
||||
}
|
||||
// Add the recent subjects entry for the new subject; must
|
||||
// be called after we update msg.subject
|
||||
process_message_for_recent_subjects(msg);
|
||||
});
|
||||
}
|
||||
|
||||
var row = current_msg_list.get_row(event.message_id);
|
||||
|
|
|
@ -1134,6 +1134,9 @@ table.focused_table {
|
|||
.message_edit_content {
|
||||
line-height: 18px;
|
||||
}
|
||||
.message_edit_topic_propagate{
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.message_content.condensed {
|
||||
max-height: 8.5em;
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
<label class="control-label edit-control-label" for="message_edit_topic">Topic</label>
|
||||
<div class="controls edit-controls">
|
||||
<input type="text" value="{{topic}}" class="message_edit_topic" id="message_edit_topic">
|
||||
<label class='message_edit_topic_propagate'>
|
||||
<input type="checkbox"> Change all later messages on this topic
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
|
|
@ -1026,7 +1026,7 @@ def do_update_onboarding_steps(user_profile, steps):
|
|||
users=[user_profile.id])
|
||||
tornado_callbacks.send_notification(notice)
|
||||
|
||||
def do_update_message(user_profile, message_id, subject, content):
|
||||
def do_update_message(user_profile, message_id, subject, propagate_subject, content):
|
||||
try:
|
||||
message = Message.objects.select_related().get(id=message_id)
|
||||
except Message.DoesNotExist:
|
||||
|
@ -1036,6 +1036,7 @@ def do_update_message(user_profile, message_id, subject, content):
|
|||
'sender': user_profile.email,
|
||||
'message_id': message_id}
|
||||
edit_history_event = {}
|
||||
changed_messages = [message]
|
||||
|
||||
if message.sender != user_profile:
|
||||
if not (message.subject == "(no topic)" and content is None):
|
||||
|
@ -1078,17 +1079,36 @@ def do_update_message(user_profile, message_id, subject, content):
|
|||
event["rendered_content"] = rendered_content
|
||||
|
||||
if subject is not None:
|
||||
orig_subject = message.subject
|
||||
subject = subject.strip()
|
||||
if subject == "":
|
||||
raise JsonableError("Topic can't be empty")
|
||||
|
||||
if len(subject) > MAX_SUBJECT_LENGTH:
|
||||
raise JsonableError("Topic too long")
|
||||
event["orig_subject"] = message.subject
|
||||
event["orig_subject"] = orig_subject
|
||||
message.subject = subject
|
||||
event["subject"] = subject
|
||||
event['subject_links'] = bugdown.subject_links(message.sender.realm.domain.lower(), subject)
|
||||
edit_history_event["prev_subject"] = event['orig_subject']
|
||||
edit_history_event["prev_subject"] = orig_subject
|
||||
|
||||
if propagate_subject:
|
||||
messages = Message.objects.filter(
|
||||
recipient = message.recipient,
|
||||
subject = orig_subject,
|
||||
id__gt = message.id
|
||||
).select_related()
|
||||
|
||||
# Evaluate the query before running the update
|
||||
messages_list = list(messages)
|
||||
messages.update(subject=subject)
|
||||
|
||||
for m in messages_list:
|
||||
# The cached ORM object is not changed by messages.update()
|
||||
# and the memcached update requires the new value
|
||||
m.subject = subject
|
||||
|
||||
changed_messages += messages_list
|
||||
|
||||
message.last_edit_time = timezone.now()
|
||||
event['edit_timestamp'] = datetime_to_timestamp(message.last_edit_time)
|
||||
|
@ -1107,12 +1127,15 @@ def do_update_message(user_profile, message_id, subject, content):
|
|||
# Update the message as stored in both the (deprecated) message
|
||||
# cache (for shunting the message over to Tornado in the old
|
||||
# get_messages API) and also the to_dict caches.
|
||||
cache_save_message(message)
|
||||
items_for_memcached = {}
|
||||
items_for_memcached[to_dict_cache_key(message, True)] = \
|
||||
(stringify_message_dict(message.to_dict_uncached(apply_markdown=True)),)
|
||||
items_for_memcached[to_dict_cache_key(message, False)] = \
|
||||
(stringify_message_dict(message.to_dict_uncached(apply_markdown=False)),)
|
||||
event['message_ids'] = []
|
||||
for changed_message in changed_messages:
|
||||
event['message_ids'].append(changed_message.id)
|
||||
cache_save_message(changed_message)
|
||||
items_for_memcached[to_dict_cache_key(changed_message, True)] = \
|
||||
(stringify_message_dict(changed_message.to_dict_uncached(apply_markdown=True)),)
|
||||
items_for_memcached[to_dict_cache_key(changed_message, False)] = \
|
||||
(stringify_message_dict(changed_message.to_dict_uncached(apply_markdown=False)),)
|
||||
cache_set_many(items_for_memcached)
|
||||
|
||||
recipients = [um.user_profile_id for um in UserMessage.objects.filter(message=message_id)]
|
||||
|
|
|
@ -1267,10 +1267,11 @@ def json_fetch_raw_message(request, user_profile,
|
|||
def update_message_backend(request, user_profile,
|
||||
message_id=REQ(converter=to_non_negative_int),
|
||||
subject=REQ(default=None),
|
||||
propagate_subject=REQ(default=False),
|
||||
content=REQ(default=None)):
|
||||
if subject is None and content is None:
|
||||
return json_error("Nothing to change")
|
||||
do_update_message(user_profile, message_id, subject, content)
|
||||
do_update_message(user_profile, message_id, subject, propagate_subject, content)
|
||||
return json_success()
|
||||
|
||||
# We do not @require_login for send_message_backend, since it is used
|
||||
|
|
Loading…
Reference in New Issue