From db201707bf533c654e2478f98e8f2eb6d0b05454 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 29 Mar 2021 23:22:54 -0500 Subject: [PATCH 1/2] Middle-click account to open it in a new tab, fixes #603 --- app/soapbox/actions/auth.js | 4 ++-- app/soapbox/components/dropdown_menu.js | 19 +++++++++++++++++++ .../ui/components/profile_dropdown.js | 14 +++++++++++--- app/soapbox/reducers/auth.js | 17 +++++++++++++---- 4 files changed, 45 insertions(+), 9 deletions(-) diff --git a/app/soapbox/actions/auth.js b/app/soapbox/actions/auth.js index e99ad9fdb..8f6345508 100644 --- a/app/soapbox/actions/auth.js +++ b/app/soapbox/actions/auth.js @@ -190,8 +190,8 @@ export function logOut() { }; } -export function switchAccount(accountId) { - return { type: SWITCH_ACCOUNT, accountId }; +export function switchAccount(accountId, reload = true) { + return { type: SWITCH_ACCOUNT, accountId, reload }; } export function fetchOwnAccounts() { diff --git a/app/soapbox/components/dropdown_menu.js b/app/soapbox/components/dropdown_menu.js index abaea33fe..056070329 100644 --- a/app/soapbox/components/dropdown_menu.js +++ b/app/soapbox/components/dropdown_menu.js @@ -117,6 +117,24 @@ class DropdownMenu extends React.PureComponent { } } + handleMiddleClick = e => { + const i = Number(e.currentTarget.getAttribute('data-index')); + const { middleClick } = this.props.items[i]; + + this.props.onClose(); + + if (e.button === 1 && typeof middleClick === 'function') { + e.preventDefault(); + middleClick(e); + } + } + + handleAuxClick = e => { + if (e.button === 1) { + this.handleMiddleClick(e); + } + } + renderItem(option, i) { if (option === null) { return
  • ; @@ -132,6 +150,7 @@ class DropdownMenu extends React.PureComponent { tabIndex='0' ref={i === 0 ? this.setFocusRef : null} onClick={this.handleClick} + onAuxClick={this.handleAuxClick} onKeyDown={this.handleItemKeyDown} data-index={i} target={newTab ? '_blank' : null} diff --git a/app/soapbox/features/ui/components/profile_dropdown.js b/app/soapbox/features/ui/components/profile_dropdown.js index 2b3f7df7f..da638240a 100644 --- a/app/soapbox/features/ui/components/profile_dropdown.js +++ b/app/soapbox/features/ui/components/profile_dropdown.js @@ -64,6 +64,14 @@ class ProfileDropdown extends React.PureComponent { }; } + handleMiddleClick = account => { + return e => { + this.props.dispatch(switchAccount(account.get('id'), false)); + window.open('/', '_blank', 'noopener,noreferrer'); + e.preventDefault(); + }; + } + fetchOwnAccounts = throttle(() => { this.props.dispatch(fetchOwnAccounts()); }, 2000); @@ -80,7 +88,7 @@ class ProfileDropdown extends React.PureComponent { return (
    -
    +
    @@ -95,10 +103,10 @@ class ProfileDropdown extends React.PureComponent { let menu = []; - menu.push({ text: this.renderAccount(account), to: `/@${account.get('acct')}` }); + menu.push({ text: this.renderAccount(account), to: `/@${account.get('acct')}`, href: '/', middleClick: this.handleMiddleClick(account) }); otherAccounts.forEach(account => { - menu.push({ text: this.renderAccount(account), action: this.handleSwitchAccount(account) }); + menu.push({ text: this.renderAccount(account), action: this.handleSwitchAccount(account), href: '/', middleClick: this.handleMiddleClick(account) }); }); menu.push(null); diff --git a/app/soapbox/reducers/auth.js b/app/soapbox/reducers/auth.js index 51b1be464..96a22fbc8 100644 --- a/app/soapbox/reducers/auth.js +++ b/app/soapbox/reducers/auth.js @@ -54,9 +54,12 @@ const migrateLegacy = state => { }); }; +const persistAuth = state => localStorage.setItem('soapbox:auth', JSON.stringify(state.toJS())); +const persistSession = state => sessionStorage.setItem('soapbox:auth:me', state.get('me')); + const persistState = state => { - localStorage.setItem('soapbox:auth', JSON.stringify(state.toJS())); - sessionStorage.setItem('soapbox:auth:me', state.get('me')); + persistAuth(state); + persistSession(state); }; const initialize = state => { @@ -151,6 +154,7 @@ const userSwitched = (oldState, state) => { }; const maybeReload = (oldState, state, action) => { + if (action.reload === false) return; if (userSwitched(oldState, state)) { reload(state); } @@ -159,9 +163,14 @@ const maybeReload = (oldState, state, action) => { export default function auth(oldState = initialState, action) { const state = reducer(oldState, action); - // Persist the state in localStorage if (!state.equals(oldState)) { - persistState(state); + // Persist the state in localStorage + persistAuth(state); + + // Persist the session + if (action.reload !== false) { + persistSession(state); + } // Reload the page under some conditions maybeReload(oldState, state, action); From 32b3173604fcb6b95c0f424785745fbc46b30481 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 29 Mar 2021 23:26:50 -0500 Subject: [PATCH 2/2] Set href for menu items with to --- app/soapbox/components/dropdown_menu.js | 4 ++-- app/soapbox/features/ui/components/profile_dropdown.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/soapbox/components/dropdown_menu.js b/app/soapbox/components/dropdown_menu.js index 056070329..2f2412928 100644 --- a/app/soapbox/components/dropdown_menu.js +++ b/app/soapbox/components/dropdown_menu.js @@ -140,12 +140,12 @@ class DropdownMenu extends React.PureComponent { return
  • ; } - const { text, href = '#', newTab, isLogout } = option; + const { text, href, to, newTab, isLogout } = option; return (
  • { menu.push({ text: this.renderAccount(account), action: this.handleSwitchAccount(account), href: '/', middleClick: this.handleMiddleClick(account) });