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
messageActionSheet: Add option to copy link of message to clipboard #3412
Conversation
Thanks @ishammahajan !
|
Also:
|
@gnprice thanks for the review!
|
b969f0b
to
ecaa4c4
Compare
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.
nice work @ishammahajan 👍
Left few comments :)
src/utils/message.js
Outdated
@@ -52,3 +52,24 @@ export const findAnchor = ( | |||
const firstUnreadMessage = findFirstUnread(messages, flags, subscriptions, mute); | |||
return firstUnreadMessage ? firstUnreadMessage.id : 0; | |||
}; | |||
|
|||
export const getLinkToMessage = (auth: Auth, message: Message): string => { | |||
// Display_recipient contains name of stream or an array of users. |
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 guess better place for this is modelTypes.js
display_recipient: $FlowFixMe, // `string` for type stream, else PmRecipientUser[].
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.
Will fix. It's a trace left behind from a previous version.
src/utils/message.js
Outdated
@@ -11,7 +11,7 @@ export const shouldBeMuted = ( | |||
subscriptions: Subscription[] = [], | |||
mutes: MuteState = [], | |||
): boolean => { | |||
if (typeof message.display_recipient !== 'string') { | |||
if (message.type === 'private') { |
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 didn't got why this change is required?
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 isn't required, but as @gnprice pointed out, the code is cleaner and more readable this way.
For runtime conditionals, what we most often do is look at a property with a name like type, whose value is one of a few fixed strings. We design the types so that knowing that value decides what other properties will exist with what types.
In the case of Message, there's one of those with value either 'stream' or 'private'.
This also makes the tests more strict.
src/utils/__tests__/message-test.js
Outdated
|
||
describe('getLinkToMessage', () => { | ||
test('should return a stream link if message link copied from stream', () => { | ||
const auth = { realm: 'https://www.foo.bar/' }; |
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.
In other place, we are using just using zulip.com
or example
. I would not prefer to have one more category like goo.bar
:)
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 will fix this, thanks! 🙂
static/translations/messages_en.json
Outdated
@@ -50,6 +50,7 @@ | |||
"Reply": "Reply", | |||
"Add a reaction": "Add a reaction", | |||
"Copy to clipboard": "Copy to clipboard", | |||
"Copy Link to clipboard": "Copy Link to clipboard", |
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.
C
opy, L
ink are capital, but t
o and c
lipboard are small 😅
Intensional or my mistake? :)
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 seem to have forgotten to fix this, thanks for the reminder! :)
@ishammahajan It will be super great if you cloud also provide screenshots of the change (action sheet) as well. Thanks again @ishammahajan! |
@jainkuniya open source is awesome! Here is a screen recording! 😄 |
Thanks @ishammahajan for these revisions! I didn't manage to give this the time for a complete review today, sorry; will do that early next week. One quick bit:
This is really making two quite different changes:
Those should be separate commits; this is an example of making clear and coherent commits. That will help make both changes easier to understand. For one thing, it means the change to the message-content logic will get its own commit message, so you can properly explain what's changing and why 🙂 |
So, I watched the recording, and was confused for a few seconds: it didn't look like there was a link anywhere in the message you long-pressed on, so why was there a "Copy link to clipboard" option, and why did it apparently produce a link? Then I realized it was a link to the message. 😛 Even though I'd just been looking at this PR thread, the text of that option unambiguously read to me as "take this link here that you've pointed at, and copy it to the clipboard". (Which, with #3404, is a feature we'll even have in Zulip soon! 🎉) I guess this makes a sort of demonstration of this bit I said above:
|
ecaa4c4
to
99e6dab
Compare
@gnprice thanks for the review! I have separated the commits as requested and went through the link for clear and coherent commits (thanks for the link 😄).
It is rather confusing for me too, the first time I used slack I remember being confused because of the same reason. I have rather replaced it with |
7c64aa3
to
0c03bc5
Compare
@gnprice (sorry for the delay on this pr.) I've fixed some small diffs within this, the recordings do still mostly hold true, except one place where I changed the toast message for copying a message link to the more consistent Polished and ready for review! |
Bumping this for visibility. |
Thanks @ishammahajan for this PR and the update! Sorry for the delayed review. fd7a9a0 messageActionSheet: Add option to copy link of message to clipboard.
how about
Why 4 -- what's that have to do with "pm" vs "group"?
99eb302 messageActionSheet - Share function: Now returns a link along with message.
382f04c messageActionSheet - Share function: Change logic to get message content.
0c03bc5 message-test: Fix conditionals and respective tests.
|
OK, and pushed that last commit, with the |
0c03bc5
to
f7a93d3
Compare
I believe it's good, because it clarifies that
I am actually wondering why we need to pass the API key around lesser number of times, in the context of the app. As long as we don't give away the key, we should be fine, right? (I did change it in any case :))
I tried looking at what the webapp does for this, but found very little information (perhaps because I'm unfamiliar with it's architecture). Looks like it's using something like a
Certainly looks a lot cleaner! Thanks!
Ah, another convenience function. Thanks! 🙂
Okay, so. For testing out how to code these URLs properly, I took a bunch of examples from the webapp (forming a lot of groups with test accounts). I found that 3 participants in a group doesn't make it a 'group' in the eyes of the server (or at least the examples led me to believe so)! The group has to have at least 4 participants to have that Hmm, so I went to check this again. With the same group. Found that in fact the link does have the
Sure thing!
|
Yep! The idea is to make it easier to be sure we don't give away the key, by making there be a lot fewer places where we pass it around and have to think about where that information is potentially flowing to.
Thanks :)
I suspect Reading the code in that screenshot, I see that it puts up the "Copied!" alert message, but I can't actually tell how it's causing something to get copied to the clipboard, or deciding what should get copied. Perhaps ask in 7b93477 messages utils: Add
|
Oh. Sorry, what I did was just stupid 😆 .
Ah, what I meant was, that Hmm... It seems like the parameter which we would have missed,
Thanks, for that convenience feature ( |
f7a93d3
to
67929b4
Compare
The logic for getting the raw content of a message in the share function seems very finicky right now. There is no reason at all for this to continue existing especially since `copyMessageContent` (or previously `copyToClipboard`) contains some solid logic to do this exact same thing! Hence, the logic for getting the message content has been extracted to a common function called `getRawMessageContent` (`api.getRawMessageContent` for the same function from the API), and the same has been used everywhere the requirement is to extract message content. (see this comment zulip#3412 (comment) for more details)
I saw a chat thread go by where it looks like you successfully located the webapp's code corresponding to What did you learn -- what does that code look like? In particular, does it have the same behavior in all edge cases?
We only use In the recording, the spinner on the message has disappeared by the time you long-press on it. The spinner means we're still trying to send the message -- we show it precisely for I recommend using the Chrome DevTools to see the Redux state. That gives you a more direct way of seeing exactly what data we have. It's a log, so it also means you won't have to rush to look before the spinner disappears, or hack a workaround to prevent the update. |
This commit is in preparation of its child, which adds a `Copy message link` option in the message action sheet which appears when a user long presses on a message element in the webview. Appropriate tests are also added to test the behavior of this function.
There are use cases where a person wants to share a message with others who he knows have access to a particular stream. To resolve this, in this commit, another option is added in the action sheet which shows up when a message is long pressed, which copies the link of the message to the Clipboard. I have edited the buttons to say `Copy message content` for copying their content to the clipboard, and `Copy message link` to copy links which lead to the message. This commit uses the function introduced in its parent in order to find the link of the message. Fixes zulip#2623
…ssage. The share functionality is redundant at this moment because it does the very same thing as `Copy message content`. Amended that to use the new `getLinkToMessage` function to include a link along with the message contents! :)
The logic for getting the raw content of a message in the share function seems very finicky right now. There is no reason at all for this to continue existing especially since `copyMessageContent` (or previously `copyToClipboard`) contains some solid logic to do this exact same thing! Hence, the logic for getting the message content has been extracted to a common function called `getRawMessageContent` (`api.getRawMessageContent` for the same function from the API), and the same has been used everywhere the requirement is to extract message content. (see this comment zulip#3412 (comment) for more details)
@gnprice thanks for the review!
So I found that https://github.com/zulip/zulip/blob/master/static/js/hash_util.js was the file which contained the code for generating the link, specifically #L134. exports.by_conversation_and_time_uri = function (message) {
var absolute_url = window.location.protocol + "//" +
window.location.host + "/" +
window.location.pathname.split('/')[1];
var suffix = "/near/" + exports.encodeHashComponent(message.id);
if (message.type === "stream") {
return absolute_url +
exports.by_stream_topic_uri(message.stream_id, util.get_message_topic(message)) +
suffix;
}
return absolute_url + people.pm_perma_link(message) + suffix;
}; The
Ah, thanks. That makes sense! 😄 |
67929b4
to
56f0d78
Compare
Thanks @ishammahajan for the updates! Looking back at this. 0fccac9 messages utils: Add
|
This would be a very nice feature to finish, if possible! It would be a boost to people’s productivity on chat.zulip.org; I really like linking from topic to topic to make important connections and leave a trail for others (or future me) to follow when debugging or comparing related feature ideas. I can’t really write code during my commute, but I can do that! 🙂 |
Thanks for this, @ishammahajan! I'd like to take over working on this PR, if that's OK with you, and make those tweaks Greg requested in August, since this would be a really nice feature, and you've said you're quite busy, which is very understandable. Again, thank you so much for doing most of the work on this! 🙂 So I'll assign the issue to me, fix merge conflicts with the current master, work on it, and make my own PR to replace this one. |
The logic for getting the raw content of a message in the share function seems very finicky right now. There is no reason at all for this to continue existing especially since `copyMessageContent` (or previously `copyToClipboard`) contains some solid logic to do this exact same thing! Hence, the logic for getting the message content has been extracted to a common function called `getRawMessageContent` (`api.getRawMessageContent` for the same function from the API), and the same has been used everywhere the requirement is to extract message content. (see this comment zulip#3412 (comment) for more details)
Closing, to resume work in #3865. But I'll refer back to the conversation here. |
There are use cases where a person wants to share a message with others
who he knows have access to a particular stream. To resolve this, in this
commit, another option is added in the action sheet which shows up when
a message is long pressed, which copies the link of the message to the
Clipboard.
I am concerned as to whether I should include tests for either of the files
since I don't see any cases where something could go wrong. I have included
translation for only English for now, because I wanted to make sure
everything else is correct. I have also amended the
share
functionalityto include a sweet little message which contains the link to the stream to
make it more useful. Please advise on both the tests and this.
Fixes #2623