Skip to content
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

stop-redirecting-in-notification-bar automatically when possible #3173

Closed
fregante opened this issue Jun 4, 2020 · 14 comments · Fixed by #3189
Closed

stop-redirecting-in-notification-bar automatically when possible #3173

fregante opened this issue Jun 4, 2020 · 14 comments · Fixed by #3189

Comments

@fregante
Copy link
Member

fregante commented Jun 4, 2020

As discussed in #2952 and #3036

I think stop-redirecting-in-notification-bar can be done automatically if the user opened the notification in a new tab.

For example:

  1. disable automatic redirect for all buttons, always
  2. try calling history.back() (unless alt is pressed)

If you opened the notification in a new tab, history.back() won't have any effect.

IMHO this makes sense since in that case, the notifications list is still open in its own tab.

PR welcome if you test that this works as expected in both browsers.

cc @FloEdelmann @karlhorky @tonglil

@fregante
Copy link
Member Author

fregante commented Jun 4, 2020

I think this however doesn't work that well/easily on PRs since they have multiple tabs and the bar is persisted. Example:

  1. Open PR notification
  2. Visit Files tab
  3. Press "Done"

You won't be redirected back to the notification list but only back to the Conversation tab. 😕

@FloEdelmann
Copy link
Member

FloEdelmann commented Jun 4, 2020

Thanks @fregante!

I was already writing an extensive response in #3036 to @tonglil and @karlhorky, but just threw it away because your suggestion is much better!

@karlhorky
Copy link
Contributor

karlhorky commented Jun 4, 2020

Sounds interesting. I was also going to bring up the potential bugs with history.back() going back to a different page than the notifications.

What about navigating to the Notifications page only if you have a history? Eg:

if (history.length > 1) {
  location.href = 'https://github.com/notifications';
}

@fregante
Copy link
Member Author

fregante commented Jun 4, 2020

OMG I never knew about history.length, I just assumed it was not public information due to security.

It does get more complicated in this situation, but perhaps it's still possible with some ingenuity.

Perhaps it's as easy as:

// Enable behavior only if it's a new tab
if isPR && history.length > 1
  // Remember Notifications List position in history
  notifications = history.length - 1

  // Return to notifications list when the buttons are clicked
  buttons.onclick = () => history.go(notifications - history.length)

It gets a little more complicated when the pages don't load via ajax, so in that case we'd have to preserve this information somehow, maybe:

if (isPR && history.length > 1) || sessionstorage.rghHistory
  ...


  // Store position before navigation
  onbeforeunload = () => sessionstorage.rghHistory = notifications

  // Delete storage if any, it only needs to exist between pageloads
  delete sessionstorage.rghHistory

@karlhorky
Copy link
Contributor

Hm, ok... I'm probably not understanding all of the complexity involved in this. I thought it would be simpler code than that.

Any reason why it wouldn't work with location.href =?

@karlhorky
Copy link
Contributor

karlhorky commented Jun 4, 2020

Another option would be to leave all of the existing code as it is, and only add the condition of history.length === 1.

So something like:

function handleClick(event: delegate.Event<MouseEvent, HTMLButtonElement>): void {
    // Disable the redirect to the Notifications inbox if either:
    // 1. The alt key was held down during click
    // 2. The history length is `1` (a new tab)
    const redirectDisabled = event.alt || history.length === 1;
    event.delegateTarget.form!.toggleAttribute('data-redirect-to-inbox-on-submit', !redirectDisabled);
}

@FloEdelmann
Copy link
Member

leave all of the existing code as it is, and only add the condition of history.length === 1

I think that solution might work well and without much code changes. We just need to store the history.length in the init function, so that navigating around in that new tab (e.g. to the PR's Files tab) while the notification is still visible doesn't change the behavior.

@fregante
Copy link
Member Author

fregante commented Jun 4, 2020

Absolutely! History.go is unnecessary since we have the length now.

However the sessionStorage part enables this on PRs as well, or else this feature won’t work if the user goes to the Files tab after opening a PR: history.length will be 2

@karlhorky
Copy link
Contributor

Got it, so something like the following?

function handleClick(event: delegate.Event<MouseEvent, HTMLButtonElement>): void {
    // Disable the redirect to the Notifications inbox if either:
    // 1. The alt key was held down during click
    // 2. The notification has been opened in a new tab
    const redirectDisabled = event.alt || sessionStorage.rghIsNewTab;
    event.delegateTarget.form!.toggleAttribute('data-redirect-to-inbox-on-submit', !redirectDisabled);
    delete sessionStorage.rghIsNewTab;
}

async function init(): Promise<void> {
    // If the history length is `1` on init, the
    // notification has been opened in a new tab
    sessionStorage.rghIsNewTab = history.length === 1;
	delegate(document, '.notification-shelf .js-notification-action button', 'click', handleClick);
}

@fregante
Copy link
Member Author

fregante commented Jun 5, 2020

SessionStorage is shared across tabs, so it should exist for as little as possible to avoid conflicts. To do this, set it onbeforeunload and read+unset it in init

@FloEdelmann
Copy link
Member

FloEdelmann commented Jun 5, 2020

SessionStorage is shared across tabs

No, it's not. https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage:

Opening a page in a new tab or window creates a new session with the value of the top-level browsing context, which differs from how session cookies work.

I don't think we need to delete the session storage item at all, because it will only exist in this tab; and when opening another notification, its init function will set it again to a new value.

Also, when clicking on the same notification bar multiple times, it should not behave differently. In other words; don't delete sessionStorage.rghIsNewTab; when clicking on "Done" in a new tab, because a subsequent click on "Move to inbox" would redirect to notifications page again.

@fregante
Copy link
Member Author

fregante commented Jun 5, 2020

No, it's not. developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage:

Indeed! Thanks for checking. I was confusing it with localStorage

@FloEdelmann
Copy link
Member

@karlhorky Would you open a PR with your suggested changes, or do you want me to do it?

@karlhorky
Copy link
Contributor

If this code is acceptable, happy to open a PR. How does this look? #3189

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging a pull request may close this issue.

3 participants