Skip to content

Conversation

@thisisnitish
Copy link
Contributor

Show Alert when when we try to create a stream with an existing name.

Fixes: #5199

Copy link
Contributor

@chrisbobbe chrisbobbe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @thisisnitish! See a few small comments below.

Comment on lines 25 to 26
const getStreams = useSelector(getStreamsByName);
const allStreams = Array.from(getStreams.keys());
Copy link
Contributor

@chrisbobbe chrisbobbe Apr 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The getStreamsByName selector gives a Map<string, Stream>, i.e., a Map where keys are strings and values are Streams. As the name suggests, the keys are stream names.

Map gives you a way to see if there's a value at a given key, so you don't need to make an Array to see if we know about a stream: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, @chrisbobbe!, Today evening, I got the idea of this i.e. has and kind of realised that, I need to change here 😉 and thankfully you pointed out.

Comment on lines 30 to 38
if (allStreams.includes(name)) {
showErrorAlert('A Stream with this name already exists');
} else {
api.createStream(auth, name, description, [ownEmail], isPrivate);
NavigationService.dispatch(navigateBack());
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of putting the normal, happy-case code in an else, let's use the "early return" pattern here. So, in the if, just after the showErrorAlert line, add a return line. Then pull what's currently in the else block outward. Like this:

      if (allStreams.includes(name)) {
        showErrorAlert('A Stream with this name already exists');
        return;
      }

      api.createStream(auth, name, description, [ownEmail], isPrivate);
      NavigationService.dispatch(navigateBack());

For Greg's reasoning about this preference, see #4980 (comment) .

api.createStream(auth, name, description, [ownEmail], isPrivate);
NavigationService.dispatch(navigateBack());
if (allStreams.includes(name)) {
showErrorAlert('A Stream with this name already exists');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lowercase "stream", and put a period at the end: "A stream with this name already exists."

Then, please add an entry to static/translations/messages_en.json, as mentioned in our translations doc (docs/howto/translations.md).

(name: string, description: string, isPrivate: boolean) => {
api.createStream(auth, name, description, [ownEmail], isPrivate);
NavigationService.dispatch(navigateBack());
if (allStreams.includes(name)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's an edge case that I'm not sure how best to handle. I think it shouldn't block progress on the PR, but it'd be good to write it down in a code comment here, so at least the behavior is clear.

It's possible that a stream exists but the client doesn't know about it, for example, if it's a private stream that the user can't access.

Maybe something like

      // This will miss existing streams that the client can't know about;
      // for example, a private stream the user can't access.

just above the if line.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it shouldn't block progress on the PR

Ah, I take that back; Greg has suggested something to do about this: https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/.23M5199/near/1364442

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure @chrisbobbe!, Thanks for thinking about this edge case. I think we forgot to discuss this edge case in our discussion. I'll add it.
Thanks 😊

import { useSelector } from '../react-redux';
import { navigateBack } from '../actions';
import { getAuth, getOwnEmail } from '../selectors';
import { getStreamsByName } from '../subscriptions/subscriptionSelectors';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

streams: Show alert when stream name already exists.

Show Alert when when we try to create a stream with an existing name.

Fixes: https://github.com/zulip/zulip-mobile/issues/5199

Commit message nit: Let's link to the discussion where we decided on this approach; perhaps here: https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/.23M5199/near/1363029 .

There were a few things that suggested this approach instead of others (one being the awkwardness of the server API); it could be helpful context in case we look into changing the design in the future.

@thisisnitish
Copy link
Contributor Author

Thanks for review @chrisbobbe!, I've made changes to the PR. Please have a look. Thanks 😊

Copy link
Contributor

@chrisbobbe chrisbobbe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the revision. Please see one small comment below. Also, did you see #5331 (comment) ?

export default function CreateStreamScreen(props: Props): Node {
const auth = useSelector(getAuth);
const ownEmail = useSelector(getOwnEmail);
const getStreams = useSelector(getStreamsByName);
Copy link
Contributor

@chrisbobbe chrisbobbe Apr 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getStreams isn't the right name for this variable, which holds a Map<string, Stream> value. It makes it sound like the value is a function that, when called, will "get streams".

Let's use streamsByName. That's a more natural name for the result of using the getStreamsByName selector.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure @chrisbobbe!, I'll change the name.

@thisisnitish
Copy link
Contributor Author

thisisnitish commented Apr 12, 2022

Also, did you see #5331 (comment) ?

Yes @chrisbobbe!, I read that comment.
So, now we want to handle the edge case where, the stream already exists and user isn't aware of the stream because the stream itself is a private stream.
So as per the suggestion from https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/.23M5199/near/1363029, the server will always throw an error and we have handle that error from the server.

So, I've one more doubt @chrisbobbe!, I'm still not able to understand

we have handle that error from the server.

It would be a great help, if you could explain this line a little. Thanks 😊

@chrisbobbe
Copy link
Contributor

@thisisnitish
Copy link
Contributor Author

Hey @chrisbobbe!, I made some changes please have a look.
Here is the preview

Simulator.Screen.Recording.-.iPhone.12.-.2022-04-30.at.19.18.43.mp4

I hope this will be fine 🤞🏻
Thanks 😊

Show Alert when when we try to create a stream with an existing name.
Refer Discussion:
https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/.23M5199/near/1363029

Fixes: zulip#5199
Co-authored-by: Chris Bobbe <[email protected]>
@chrisbobbe chrisbobbe force-pushed the stream_name_exist branch 2 times, most recently from 1c90b66 to 0200c1e Compare May 2, 2022 23:37
Copy link
Contributor

@chrisbobbe chrisbobbe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

I've just rebased, resolving some rebase conflicts with some recent work I did. I'll go ahead and merge, with a few fixes:

  • I noticed that we weren't using _ for the 'A stream with this name already exists' text; I've done that.
  • I squashed the two commits together; see comments.

About the second point, here's a note about the benefits of Zulip's version-control philosophy:

Zulip's commit discipline makes review easier and it makes the project's history clearer. (You may have used Greg's "secret" to browsing history so many times that it's instinctive by now. If not, I recommend it!) Our style lets us confidently make complex changes. A clean record of the code's history is useful for everybody, especially new contributors and anyone reading commits years after they were written.

Comment on lines 41 to 49
// If the stream already exists but you can't access it (e.g., it's
// private), then it won't be in the client's data structures, so our
// client-side check won't stop the request from being made. In that case,
// we expect the server to always give an error, because you can't subscribe
// to a stream that you can't access. That error will have:
// - error.message: `Unable to access stream (${streamName})`, or a
// translation of that into the user's own language
// - error.code: "BAD_REQUEST" (as of server feature level 126; possibly
// the server should be more specific)
Copy link
Contributor

@chrisbobbe chrisbobbe May 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. Your second commit—

Added Comments before showing alert for accessing Private Stream.

Refer dicussion: https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/.23M5199.20error.20for.20name.20collision.20on.20creating.20stream

—is best squashed into the first. Its behavior changes are part of showing an alert when a stream name is unavailable, which is what the first commit is about. I'll squash it myself, but please develop the habit of submitting coherent commits for review, and please ask questions, or find examples yourself, when you're not sure how best to do that.

Also (and this won't be relevant once I squash the commits together, but for the future): the commit message of this second commit is very misleading. It makes it sound like the added comment is the only thing that changes in the commit. Comments don't change how the app behaves, so it sounds like the app's behavior doesn't change in this commit. But that's not true: the commit adds handling of the error from the server. If a commit intentionally changes the app's behavior, that fact should be obvious in the commit message, preferably in the summary line. Otherwise, the behavior changes are easy to miss and will appear accidental or poorly planned, which this change is not. 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Umm, Sorry @chrisbobbe! for this one. Actually, I forgot to squash the commits. From now onwards, I'll keep this in mind. Thanks 😊

// This will miss existing streams that the client can't know about;
// for example, a private stream the user can't access.
if (getStreams.has(name)) {
if (streamsByName.has(name)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This rename should be squashed into the commit that added the wrong name, so there aren't any commits with the wrong name. I'll take care of that before merging.

@chrisbobbe chrisbobbe force-pushed the stream_name_exist branch from 0200c1e to 1c90b66 Compare May 2, 2022 23:45
@chrisbobbe chrisbobbe merged commit 1c90b66 into zulip:main May 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Not Showing any alert if stream name already exist.

2 participants