Skip to content
This repository has been archived by the owner on Dec 11, 2019. It is now read-only.

Commit

Permalink
Refine tab's element position
Browse files Browse the repository at this point in the history
  • Loading branch information
cezaraugusto committed Jan 8, 2017
1 parent ba01f6c commit 33dc2dc
Show file tree
Hide file tree
Showing 7 changed files with 220 additions and 54 deletions.
4 changes: 3 additions & 1 deletion app/renderer/components/styles/global.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ const globalStyles = {
navbarBraveButtonMarginLeft: '80px',
navbarLeftMarginDarwin: '76px',
sideBarWidth: '190px',
aboutPageSectionPadding: '24px'
aboutPageSectionPadding: '24px',
defaultIconPadding: '0 2px',
defaultTabPadding: '0 4px'
},
shadow: {
switchShadow: 'inset 0 1px 4px rgba(0, 0, 0, 0.35)',
Expand Down
16 changes: 16 additions & 0 deletions app/renderer/components/styles/tab.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

const tabStyles = {
breakpoint: {
medium: '83px',
small: '66px',
extraSmall: '53px',
hiddenSecondaryIcon: '42px',
faviconOnly: '33px',
hiddenFavicon: '16px'
}
}

module.exports = tabStyles
9 changes: 5 additions & 4 deletions app/renderer/components/tabIcon.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,13 @@ const styles = StyleSheet.create({
'icon': {
backgroundPosition: 'center',
backgroundRepeat: 'no-repeat',
display: 'inline-block',
display: 'flex',
fontSize: '14px',
margin: 'auto 7px auto 7px',
position: 'relative',
verticalAlign: 'middle',
textAlign: 'center'
textAlign: 'center',
justifyContent: 'center',
width: '16px',
padding: globalStyles.spacing.defaultIconPadding
},
'blueIcon': {
color: globalStyles.color.highlightBlue
Expand Down
166 changes: 130 additions & 36 deletions js/components/tab.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

const React = require('react')

const ImmutableComponent = require('./immutableComponent')

const windowActions = require('../actions/windowActions')
const locale = require('../l10n')
const dragTypes = require('../constants/dragTypes')
Expand All @@ -18,14 +16,20 @@ const contextMenus = require('../contextMenus')
const dnd = require('../dnd')
const windowStore = require('../stores/windowStore')
const ipc = require('electron').ipcRenderer
const throttle = require('../lib/throttle')

const tabStyles = require('../../app/renderer/components/styles/tab')
const {TabIcon, AudioTabIcon} = require('../../app/renderer/components/tabIcon')

class Tab extends ImmutableComponent {
class Tab extends React.Component {
constructor () {
super()
this.onMouseEnter = this.onMouseEnter.bind(this)
this.onMouseLeave = this.onMouseLeave.bind(this)
this.onUpdateTabSize = this.onUpdateTabSize.bind(this)
this.state = {
tabWidth: this.tabSize
}
}
get frame () {
return windowStore.getFrame(this.props.tab.get('frameKey'))
Expand All @@ -34,6 +38,27 @@ class Tab extends ImmutableComponent {
return !!this.props.tab.get('pinnedLocation')
}

get tabBreakpoint () {
const tabWidth = this.state.tabWidth

const medium = tabWidth <= Number.parseInt(tabStyles.breakpoint.medium, 10)
const small = tabWidth <= Number.parseInt(tabStyles.breakpoint.small, 10)
const extraSmall = tabWidth <= Number.parseInt(tabStyles.breakpoint.extraSmall, 10)
const hiddenSecondaryIcon = tabWidth <= Number.parseInt(tabStyles.breakpoint.hiddenSecondaryIcon, 10)
const faviconOnly = tabWidth <= Number.parseInt(tabStyles.breakpoint.faviconOnly, 10)
const hiddenFavicon = tabWidth <= Number.parseInt(tabStyles.breakpoint.hiddenFavicon, 10)

return {
medium, small, extraSmall, hiddenSecondaryIcon, faviconOnly, hiddenFavicon
}
}

get tabSize () {
const tab = this.tabNode
// Avoid TypeError keeping it null until component is mounted
return tab && !this.isPinned ? tab.getBoundingClientRect().width : null
}

get draggingOverData () {
if (!this.props.draggingOverData ||
this.props.draggingOverData.get('dragOverKey') !== this.props.tab.get('frameKey')) {
Expand All @@ -52,6 +77,26 @@ class Tab extends ImmutableComponent {
return this.props.draggingOverData
}

onUpdateTabSize () {
// Avoid calling setState on unmounted component
// when user switch to a new tabSet
if (this.tabNode) this.setState({tabWidth: this.tabSize})
}

componentWillMount () {
this.onUpdateTabSize()
}

componentDidMount () {
this.onUpdateTabSize()
// Execute resize handler at a rate of 15fps
window.addEventListener('resize', throttle(this.onUpdateTabSize, 66))
}

componentWillUnmount () {
window.removeEventListener('resize', this.onUpdateTabSize)
}

get isDragging () {
const sourceDragData = dnd.getInProcessDragData()
return sourceDragData && this.props.tab.get('frameKey') === sourceDragData.get('key')
Expand Down Expand Up @@ -148,6 +193,14 @@ class Tab extends ImmutableComponent {
}

render () {
const breakpoint = this.tabBreakpoint
const narrowView = breakpoint.extraSmall || breakpoint.hiddenSecondaryIcon || breakpoint.faviconOnly || breakpoint.hiddenFavicon
const secondaryIconIsVisible = !breakpoint.hiddenSecondaryIcon && !breakpoint.faviconOnly && !breakpoint.hiddenFavicon

let privateIconStyle = narrowView ? {padding: '0'} : null
let tabIdStyle = narrowView ? {justifyContent: 'center'} : null
let closeTabStyle = {}

// Style based on theme-color
const iconSize = 16
let iconStyle = {
Expand All @@ -165,6 +218,8 @@ class Tab extends ImmutableComponent {
}
}

const locationHasPrivateIcon = !!this.props.tab.get('isPrivate') || !!this.props.tab.get('partitionNumber')

const icon = this.props.tab.get('icon')
const defaultIcon = 'fa fa-file-o'

Expand All @@ -176,19 +231,52 @@ class Tab extends ImmutableComponent {
})
}

if (narrowView) {
closeTabStyle = Object.assign(closeTabStyle, {
right: '0'
})
iconStyle = Object.assign(iconStyle, {
padding: '0'
})
}

if (breakpoint.faviconOnly && this.props.isActive) {
Object.assign(closeTabStyle, {
opacity: '1',
width: '100%',
padding: '0',
backgroundColor: 'white',
borderTopLeftRadius: '4px',
borderTopRightRadius: '4px'
})
}

const playIconExists = !!this.props.tab.get('audioPlaybackActive') || !!this.props.tab.get('audioMuted')

let playIcon = false
let iconClass = null
if (this.props.tab.get('audioPlaybackActive') || this.props.tab.get('audioMuted')) {
if (playIconExists) {
if (this.props.tab.get('audioPlaybackActive') && !this.props.tab.get('audioMuted')) {
iconClass = 'fa fa-volume-up'
} else if (this.props.tab.get('audioPlaybackActive') && this.props.tab.get('audioMuted')) {
iconClass = 'fa fa-volume-off'
}
playIcon = true
// We don't want playIcon to be shown on small tabs
playIcon = !narrowView && !(breakpoint.small && locationHasPrivateIcon)
console.log('nao ta narrow', playIcon)
}

const locationHasFavicon = this.props.tab.get('location') !== 'about:newtab'

const audioPlayNarrowView = playIconExists && ((breakpoint.small && locationHasPrivateIcon) || narrowView)
const privateIcon = this.props.tab.get('isPrivate') && secondaryIconIsVisible
const newSessionIcon = this.props.tab.get('partitionNumber') && secondaryIconIsVisible
const closeTabButton = !this.isPinned && (!breakpoint.faviconOnly && !breakpoint.hiddenFavicon) ||
(breakpoint.faviconOnly && this.props.isActive)
const isHiddenTitle = ((breakpoint.medium || breakpoint.small) && playIconExists && locationHasPrivateIcon) ||
(breakpoint.extraSmall && locationHasPrivateIcon) ||
breakpoint.faviconOnly || breakpoint.hiddenFavicon

return <div
className={cx({
tabArea: true,
Expand All @@ -204,7 +292,9 @@ class Tab extends ImmutableComponent {
tab: true,
isPinned: this.isPinned,
active: this.props.isActive,
private: this.props.tab.get('isPrivate')
private: this.props.tab.get('isPrivate'),
noFavicon: !locationHasFavicon,
alternativePlayIndicator: audioPlayNarrowView
})}
data-frame-key={this.props.tab.get('frameKey')}
ref={(node) => { this.tabNode = node }}
Expand All @@ -216,47 +306,51 @@ class Tab extends ImmutableComponent {
onClick={this.onClickTab.bind(this)}
onContextMenu={contextMenus.onTabContextMenu.bind(this, this.frame)}
style={activeTabStyle}>
<div className='tabId' style={tabIdStyle}>
{
(locationHasFavicon && !breakpoint.hiddenFavicon) || this.isPinned
? <div className={cx({
tabIcon: true,
bookmarkFile: !icon,
[defaultIcon]: !icon,
'fa fa-circle-o-notch fa-spin': this.loading
})}
style={iconStyle} />
: null
}
{
!this.isPinned && !isHiddenTitle
? <div className='tabTitle'>
{this.displayValue}
</div>
: null
}
{
playIcon
? <AudioTabIcon styles={iconClass}
onClick={this.onMuteFrame.bind(this, !this.props.tab.get('audioMuted'))} />
: null
}
</div>
{
this.props.tab.get('isPrivate')
? <TabIcon styles='fa fa-eye' />
privateIcon
? <TabIcon styles='fa fa-eye' style={privateIconStyle} />
: null
}
{
this.props.tab.get('partitionNumber')
newSessionIcon
? <TabIcon l10nArgs={JSON.stringify({partitionNumber: this.props.tab.get('partitionNumber')})}
l10nId='sessionInfoTab'
styles='fa fa-user' />
: null
}
{
locationHasFavicon
? <div className={cx({
tabIcon: true,
bookmarkFile: !icon,
[defaultIcon]: !icon,
'fa fa-circle-o-notch fa-spin': this.loading
})}
style={iconStyle} />
: null
}
{
playIcon
? <AudioTabIcon styles={iconClass}
onClick={this.onMuteFrame.bind(this, !this.props.tab.get('audioMuted'))} />
: null
}
{
!this.isPinned
? <div className='tabTitle'>
{this.displayValue}
</div>
styles='fa fa-user'
style={privateIconStyle} />
: null
}
{
!this.isPinned
closeTabButton
? <span onClick={this.onCloseFrame.bind(this)}
data-l10n-id='closeTabButton'
className='closeTab fa fa-times-circle' />
className='closeTab fa fa-times-circle'
style={closeTabStyle} />
: null
}
</div>
Expand Down
20 changes: 20 additions & 0 deletions js/lib/throttle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

'use strict'

function throttle (fn, limit) {
let waitingTime = false
return () => {
if (!waitingTime) {
fn.call()
waitingTime = true
setTimeout(() => {
waitingTime = false
}, limit)
}
}
}

module.exports = throttle
Loading

0 comments on commit 33dc2dc

Please sign in to comment.