Skip to content

Commit

Permalink
Merge pull request brave#9414 from NejcZdovc/redux/tabPage
Browse files Browse the repository at this point in the history
Refactors TabPage and TabPages into redux
  • Loading branch information
bsclifton authored Jun 15, 2017
2 parents a6561e7 + 07fc91b commit ed4824b
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 40 deletions.
5 changes: 1 addition & 4 deletions app/renderer/components/main/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -832,10 +832,7 @@ class Main extends ImmutableComponent {
onContextMenu={this.onTabContextMenu}>
{
nonPinnedFrames.size > tabsPerPage
? <TabPages frames={nonPinnedFrames}
tabsPerTabPage={tabsPerPage}
previewTabPage={getSetting(settings.SHOW_TAB_PREVIEWS)}
tabPageIndex={this.props.windowState.getIn(['ui', 'tabs', 'tabPageIndex'])} />
? <TabPages />
: null
}
</div>
Expand Down
66 changes: 52 additions & 14 deletions app/renderer/components/tabs/tabPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,44 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */

const React = require('react')
const Immutable = require('immutable')

// Components
const ImmutableComponent = require('../immutableComponent')
const ReduxComponent = require('../reduxComponent')

// Actions
const appActions = require('../../../../js/actions/appActions')
const windowActions = require('../../../../js/actions/windowActions')

// Constants
const dragTypes = require('../../../../js/constants/dragTypes')
const settings = require('../../../../js/constants/settings')

// Utils
const {getSetting} = require('../../../../js/settings')
const cx = require('../../../../js/lib/classSet')
const {onTabPageContextMenu} = require('../../../../js/contextMenus')
const {getCurrentWindowId} = require('../../currentWindow')
const dndData = require('../../../../js/dndData')
const frameStateUtil = require('../../../../js/state/frameStateUtil')
const dnd = require('../../../../js/dnd')

class TabPage extends ImmutableComponent {
constructor () {
super()
class TabPage extends React.Component {
constructor (props) {
super(props)
this.onMouseEnter = this.onMouseEnter.bind(this)
this.onMouseLeave = this.onMouseLeave.bind(this)
}

onMouseLeave () {
window.clearTimeout(this.hoverTimeout)
windowActions.setPreviewTabPageIndex()
}

onMouseEnter (e) {
// relatedTarget inside mouseenter checks which element before this event was the pointer on
// relatedTarget inside mouse enter checks which element before this event was the pointer on
// if this element has a tab-like class, then it's likely that the user was previewing
// a sequency of tabs. Called here as previewMode.
// a sequence of tabs. Called here as previewMode.
const previewMode = /tab(?!pages)/i.test(e.relatedTarget.classList)

// If user isn't in previewMode, we add a bit of delay to avoid tab from flashing out
Expand All @@ -44,21 +50,20 @@ class TabPage extends ImmutableComponent {
}

onDrop (e) {
if (this.props.tabPageFrames.size === 0) {
if (this.props.isPageEmpty) {
return
}

appActions.dataDropped(getCurrentWindowId())

const moveToFrame = this.props.tabPageFrames.get(0)
const sourceDragData = dndData.getDragData(e.dataTransfer, dragTypes.TAB)
const sourceDragFromPageIndex = this.props.sourceDragFromPageIndex
// This must be executed async because the state change that this causes
// will cause the onDragEnd to never run
setTimeout(() => {
// If we're moving to a right page, then we're already shifting everything to the left by one, so we want
// to drop it on the right.
windowActions.moveTab(sourceDragData.get('key'), moveToFrame.get('key'),
windowActions.moveTab(sourceDragData.get('key'), this.props.moveToFrameKey,
// Has -1 value for pinned tabs
sourceDragFromPageIndex === -1 ||
sourceDragFromPageIndex >= this.props.index)
Expand All @@ -73,22 +78,55 @@ class TabPage extends ImmutableComponent {
e.preventDefault()
}

mergeProps (state, ownProps) {
const currentWindow = state.get('currentWindow')
const frames = frameStateUtil.getNonPinnedFrames(currentWindow) || Immutable.List()
const tabsPerPage = Number(getSetting(settings.TABS_PER_PAGE))
const tabPageFrames = frames.slice(ownProps.index * tabsPerPage, (ownProps.index * tabsPerPage) + tabsPerPage)
const isAudioPlaybackActive = tabPageFrames.find((frame) =>
frame.get('audioPlaybackActive') && !frame.get('audioMuted'))

let sourceDragFromPageIndex
const sourceDragData = dnd.getInterBraveDragData()
if (sourceDragData) {
sourceDragFromPageIndex = frames.findIndex((frame) => frame.get('key') === sourceDragData.get('key'))

if (sourceDragFromPageIndex !== -1) {
sourceDragFromPageIndex /= tabsPerPage
}
}

const props = {}
// used in renderer
props.index = ownProps.index
props.tabPageFrames = tabPageFrames // TODO (nejc) only primitives
props.isAudioPlaybackActive = isAudioPlaybackActive
props.previewTabPage = getSetting(settings.SHOW_TAB_PREVIEWS)
props.active = currentWindow.getIn(['ui', 'tabs', 'tabPageIndex']) === props.index

// used in other functions
props.sourceDragFromPageIndex = sourceDragFromPageIndex
props.isPageEmpty = tabPageFrames.size === 0
props.moveToFrameKey = tabPageFrames.getIn([0, 'key'])

return props
}

render () {
const audioPlaybackActive = this.props.tabPageFrames.find((frame) =>
frame.get('audioPlaybackActive') && !frame.get('audioMuted'))
return <span data-tab-page={this.props.index}
return <span
data-tab-page={this.props.index}
onDragOver={this.onDragOver.bind(this)}
onMouseEnter={this.props.previewTabPage ? this.onMouseEnter : null}
onMouseLeave={this.props.previewTabPage ? this.onMouseLeave : null}
onDrop={this.onDrop.bind(this)}
className={cx({
tabPage: true,
audioPlaybackActive,
audioPlaybackActive: this.props.isAudioPlaybackActive,
active: this.props.active})}
onContextMenu={onTabPageContextMenu.bind(this, this.props.tabPageFrames)}
onClick={windowActions.setTabPageIndex.bind(this, this.props.index)
} />
}
}

module.exports = TabPage
module.exports = ReduxComponent.connect(TabPage)
37 changes: 17 additions & 20 deletions app/renderer/components/tabs/tabPages.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,34 @@
const React = require('react')

// Components
const ImmutableComponent = require('../immutableComponent')
const ReduxComponent = require('../reduxComponent')
const TabPage = require('./tabPage')

// Utils
const dnd = require('../../../../js/dnd')
const frameStateUtil = require('../../../../js/state/frameStateUtil')

class TabPages extends React.Component {
mergeProps (state, ownProps) {
const currentWindow = state.get('currentWindow')

const props = {}
props.tabPageCount = frameStateUtil.getTabPageCount(currentWindow)

return props
}

class TabPages extends ImmutableComponent {
render () {
const tabPageCount = Math.ceil(this.props.frames.size / this.props.tabsPerTabPage)
let sourceDragFromPageIndex
const sourceDragData = dnd.getInterBraveDragData()
if (sourceDragData) {
sourceDragFromPageIndex = this.props.frames.findIndex((frame) => frame.get('key') === sourceDragData.get('key'))
if (sourceDragFromPageIndex !== -1) {
sourceDragFromPageIndex /= this.props.tabsPerTabPage
}
}
return <div className='tabPageWrap'>
{
tabPageCount > 1 &&
Array.from(new Array(tabPageCount)).map((x, i) =>
this.props.tabPageCount > 1 &&
Array.from(new Array(this.props.tabPageCount)).map((x, i) =>
<TabPage
key={`tabPage-${i}`}
tabPageFrames={this.props.frames.slice(i * this.props.tabsPerTabPage, (i * this.props.tabsPerTabPage) + this.props.tabsPerTabPage)}
previewTabPage={this.props.previewTabPage}
index={i}
sourceDragFromPageIndex={sourceDragFromPageIndex}
active={this.props.tabPageIndex === i} />)
index={i} />
)
}
</div>
}
}

module.exports = TabPages
module.exports = ReduxComponent.connect(TabPages)
10 changes: 9 additions & 1 deletion js/state/frameStateUtil.js
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,13 @@ const isValidClosedFrame = (frame) => {
return !frame.get('isPrivate')
}

const getTabPageCount = (state) => {
const frames = getNonPinnedFrames(state) || Immutable.List()
const tabsPerPage = Number(getSetting(settings.TABS_PER_PAGE))

return Math.ceil(frames.size / tabsPerPage)
}

module.exports = {
deleteTabInternalIndex,
deleteFrameInternalIndex,
Expand Down Expand Up @@ -574,5 +581,6 @@ module.exports = {
getTotalBlocks,
isPinned,
updateTabPageIndex,
isValidClosedFrame
isValidClosedFrame,
getTabPageCount
}
94 changes: 93 additions & 1 deletion test/unit/state/frameStateUtilTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,19 @@ const defaultWindowStore = Immutable.fromJS({
})

describe('frameStateUtil', function () {
let frameStateUtil
let frameStateUtil, getSettingsValue

before(function () {
getSettingsValue = 20
mockery.enable({
warnOnReplace: false,
warnOnUnregistered: false,
useCleanCache: true
})
mockery.registerMock('electron', fakeElectron)
mockery.registerMock('../settings', {
getSetting: () => getSettingsValue
})
frameStateUtil = require('../../../js/state/frameStateUtil')
this.windowState = Immutable.fromJS(Object.assign({}, defaultWindowStore.toJS()))
})
Expand Down Expand Up @@ -319,4 +323,92 @@ describe('frameStateUtil', function () {
assert.equal(result, '99+')
})
})

describe('getTabPageCount', function () {
before(function () {
getSettingsValue = 6
})

it('returns two pages when we have more tabs then the tab page limit', function () {
let state = Immutable.fromJS({
activeFrameKey: 1,
frames: [
{ key: 1 },
{ key: 2 },
{ key: 3 },
{ key: 4 },
{ key: 5 },
{ key: 6 },
{ key: 7 },
{ key: 8 }
],
framesInternal: {
index: {
1: 0,
2: 1,
3: 2,
4: 3,
5: 4,
6: 5,
7: 6,
8: 7
}
}
})
const result = frameStateUtil.getTabPageCount(state)
assert.equal(result, 2)
})

it('returns one pages when we have exactly the same tabs as the tab page limit', function () {
let state = Immutable.fromJS({
activeFrameKey: 1,
frames: [
{ key: 1 },
{ key: 2 },
{ key: 3 },
{ key: 4 },
{ key: 5 },
{ key: 6 }
],
framesInternal: {
index: {
1: 0,
2: 1,
3: 2,
4: 3,
5: 4,
6: 5
}
}
})
const result = frameStateUtil.getTabPageCount(state)
assert.equal(result, 1)
})

it('returns one pages when we have less tabs then the tab page limit', function () {
let state = Immutable.fromJS({
activeFrameKey: 1,
frames: [
{ key: 1 },
{ key: 2 },
{ key: 3 },
{ key: 4 },
{ key: 5 },
{ key: 6 }
],
framesInternal: {
index: {
1: 0,
2: 1,
3: 2,
4: 3,
5: 4,
6: 5
}
}
})
const result = frameStateUtil.getTabPageCount(state)
assert.equal(result, 1)
})
})
})

0 comments on commit ed4824b

Please sign in to comment.