-
-
Notifications
You must be signed in to change notification settings - Fork 7.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Moving topics between streams #13912
Conversation
@dobleuber can you clean up the commit history? Check out the Zulip commit guidelines for more details: https://zulip.readthedocs.io/en/latest/contributing/version-control.html |
zerver/lib/actions.py
Outdated
user_profile: UserProfile, | ||
stream: Stream, | ||
topic_name: str | ||
) -> List[Message]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line-wrapping doesn't match zulip's style. Please look at nearby code and follow our conventions.
zerver/lib/actions.py
Outdated
user_profile=user_profile | ||
) | ||
|
||
recipient = stream.recipient |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This variable is unnecessary.
zerver/lib/actions.py
Outdated
topic_name=topic_name, | ||
) | ||
|
||
return messages |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See the above, but also I think this whole function could be like 2 lines of reasonable code; you possibly should just have the caller call filter_by_topic_name_via_message
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was getting this lint error:
avoid subject as a var at zerver/lib/actions.py line 5910:
message__subject__iexact=topic_name
So I called the method filter_by_topic_name_via_message
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I just mean it could be:
query = UserMessage.objects.filter(user_profile=user_profile, message__recipient=stream.recipient)
return filter_by_topic_name_via_message(query=query, topic_name=topic_name)
Which might be better inlined unless we need it for tests.
zerver/lib/actions.py
Outdated
def do_move_topic_messages( | ||
user_profile: UserProfile, | ||
stream_origin: Stream, | ||
stream_destiny: Stream, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Call these old_stream
and new_stream
.
zerver/lib/actions.py
Outdated
user_messages = get_topic_messages(user_profile, stream_origin, topic_name) | ||
recipient_destiny = get_stream_recipient(stream_destiny.id) | ||
|
||
# We could use a bot for the breadcrump message too |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, let's change this to a message sent by Notification Bot.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mateuszmandera I just noticed we have these get_stream_recipient
and get_personal_recipient
helper functions in a few places that this code is copying; we should just remove those and use stream.recipient
etc., right? (And delete get_recipient
and its cache as well, I think???)
In any case, for this PR, @dobleuber you can just use new_stream.recipient
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@timabbott Yeah, we still have a bunch of places where we use those functions that haven't been changed. It should be pretty quick to do though and then we can remove the functions completely. I'll add it to my list.
zerver/lib/actions.py
Outdated
|
||
for user_message in user_messages: | ||
user_message.message.recipient = recipient_destiny | ||
user_message.message.save(update_fields=['recipient']) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't going to work for caching and real-time sync reasons.
See https://zulip.readthedocs.io/en/latest/subsystems/caching.html and https://zulip.readthedocs.io/en/latest/subsystems/events-system.html for details.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After some investigation, the caching situation might actually be fine, because flush_message
ignores update_fields
currently and just deletes any modified messages from the cache.
Real-time sync is going to be much more problematic; we'll need to extend the interface for "edit message" events to allow the stream to change. It shouldn't be too bad because the problem is very similar to that of topic editing which we already do that correctly for. I think ultimately what we'll want to do have this go through the edit message code path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I'll continue reviewing do_update_message
. It does a lot of things, I'm not sure if I can reuse that method (adding a stream parameter), because we could have performance issues. I'm going to continue reviewing the code, if I have any questions I'll let you know, thanks
3cb4381
to
db42c12
Compare
b4805f8
to
a3b2708
Compare
Thanks for working on this @dobleuber! I pushed back to this PR a set of commits that rewrite this to use the
The events thing may be hard for you to fix efficiently, but @dobleuber in your next pass, can you work on cleaning up the tests, changing the guard messages to use |
2ea3206
to
bfafaf1
Compare
@timabbott I worked in your last comments. |
@dobleuber can you comment on which of the TODOs noted above you resolved, and how? |
Oh! I miss the method |
9561282
to
e60953c
Compare
|
@timabbott Any feedback for this? meanwhile I am working in UI part: |
I love that UI, nice work so far @dobleuber. |
For UI, I think we should start with modifying the existing message editing UI where one can change topics to also have a "Stream" field; I think that will be a lot simpler as a way to start. |
49510b7
to
353c78d
Compare
@dobleuber I just pushed an extra commit to this PR that does an incomplete version of a refactor that I think we should do before merging this; I didn't have time to clean up the tests (etc.), but basically, my hope is to eliminate both the management command and the extra function, and just have a single code path calling I also changed the code in a way that should fix some obviously broken behavior with the breadcrumb messages (various pieces were swapped). You'll need to:
|
353c78d
to
fea7009
Compare
@timabbott I just created this issue related with your comment: #14492 |
55b3c66
to
fedb464
Compare
fedb464
to
7be3c14
Compare
@dobleuber OK I made the following changes:
The result is 843345d and 7990676. The remaining commit is just the UI, which should be the simplest part. I'm going to open a few follow-up issues before I get to looking at that, however. |
I opened #14498 for the main known bug in this feature. |
Previously, we had a restriction that we could only edit and move the topics of 7 days old messages. This buggy behaviour is now removed as in this commit. Fixes zulip#14492. Part of zulip#13912.
Previously, we had a restriction that we could only edit and move the topics of 7 days old messages. This buggy behaviour is now removed as in this commit. Fixes zulip#14492. Part of zulip#13912.
const stream_id = topic_row.attr('data-stream-id'); | ||
const topic_name = topic_row.attr('data-topic-name'); | ||
const message = home_msg_list.all_messages() | ||
.find(m => m.topic === topic_name && m.stream_id === +stream_id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check doesn't seem reliable; we may not have any messages from the topic cached in the frontend. I think the right fix is to fetch the latest message ID from stream_topic_history.js
; that is guaranteed to have data given that this widget is visible at all.
@showell is there an existing function we can call, or does one need to be added to expose "any message ID from a given stream/topic appearing in the left sidebar"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think sending a message id is the right thing here. Shouldn't it be handled better on the server side using old and new streams and topics?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, for this UI, yes; but we'll also add this to "edit a single message" UI, and for that, the message ID is an important aspect of the meaning. (Basically whenever propagate_mode != all
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh! That's good then.
if (old_topic_name && select_stream_id) { | ||
message_edit.move_message_to_stream(message_id, select_stream_id, topic_name); | ||
$('#move_topic_modal').modal('hide'); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like we're missing stopPropagation/preventDefault
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed this and pushed back here.
This initial implementation of moving a topic to another stream works as follows: * Added a method to get all topic's messages in a stream: get_topic_messages * Refactored update_message_backend method to allow changing the recipient of a message and the message topic * Created method notify_topic_moved_streams to create notifications messages whenever a messages is moved * Added a new option in topic's options to change stream * Added logic to update ui after a topic is moved * Added tests to support the code * Added documentation page for the feature
7be3c14
to
95d10a4
Compare
@@ -854,4 +854,23 @@ exports.handle_narrow_deactivated = function () { | |||
} | |||
}; | |||
|
|||
exports.move_message_to_stream = function (message_id, stream_id, topic_name) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's rename this to exports.move_topic_containing_message_to_stream
, for clarity about what it does.
And maybe add a comment right here making clear the stream_id
and topic_name
are the NEW values, and the old ones are wherever the message is located, since that may not be intuitive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I appended new_
before the variable. That is clear enough.
}, | ||
error: function (xhr) { | ||
ui_report.error(i18n.t("Error moving the topic"), xhr, | ||
$("#home-error")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you post a screenshot of this appearing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cross icon in missing from the error popup.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's probably good enough to just mark it to disappear after a few seconds.
@@ -262,6 +263,17 @@ function build_starred_messages_popover(e) { | |||
|
|||
} | |||
|
|||
function build_move_topic_to_stream_popover(e, message_id, stream_id, topic_name) { | |||
const streams = stream_data.subscribed_subs().filter(s => s.stream_id !== stream_id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's call this variable available_streams
.
I'll note that we currently include private streams in this list.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Added a TODO for keyboard navigation of the dropdown.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to exclude private streams?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, I think there's a product question about whether it's correct to limit it to just public streams. We should make a decision on that and adjust accordingly. Initially we did it just to manage complexity.
|
||
if (old_topic_name.trim() === topic_name.trim()) { | ||
topic_name = undefined; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add a comment here noting that this is intended to request no change in the topic if it didn't change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
|
||
1. Select **Move <topic name\> to another stream**. | ||
|
||
1. Select the destination stream (and if desired, enter a new topic name). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's just call it "a new topic" here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
OK, I posted a batch of mostly small comments; the main thing we need to fix here is the computation of a message ID, which hopefully @showell can help with. |
|
||
$("#move-a-topic-modal-holder").html(render_move_topic_to_stream(args)); | ||
$('#move_topic_modal').modal('show'); | ||
e.stopPropagation(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can delete this stopPropagation
; it's in the caller (and should be there)
Closing in favor of #14844; @amanagr you still still read the last few comments here. Thanks @dobleuber! |
The UI for this was merged today. Thanks again for all the work on this @dobleuber! |
Previously, we had a restriction that we could only edit and move the topics of 7 days old messages. This buggy behaviour is now removed as in this commit. Fixes zulip#14492. Part of zulip#13912.
#6427
Feature Behaviour