Skip to content

Commit

Permalink
Wrapper: add swipe-able container for menu panel
Browse files Browse the repository at this point in the history
  • Loading branch information
AquiGorka committed Feb 15, 2019
1 parent ab9bbdd commit 1df8dad
Showing 1 changed file with 151 additions and 26 deletions.
177 changes: 151 additions & 26 deletions src/Wrapper.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'
import { Gesture } from 'react-with-gesture'
import { Viewport } from '@aragon/ui'
import { Apps, Permissions, Settings } from './apps'
import AppIFrame from './components/App/AppIFrame'
Expand All @@ -22,6 +23,10 @@ import { APPS_STATUS_LOADING } from './symbols'
import { addressesEqual } from './web3-utils'
import ethereumLoadingAnimation from './assets/ethereum-loading.svg'

const THRESHOLD_DISTANCE = 10
const THRESHOLD_DIRECTION = 0.2
const THRESHOLD_PROGRESS = 0.5

class Wrapper extends React.PureComponent {
static propTypes = {
account: EthereumAddressType,
Expand All @@ -42,10 +47,12 @@ class Wrapper extends React.PureComponent {
onRequestEnable: PropTypes.func.isRequired,
permissionsLoading: PropTypes.bool.isRequired,
autoClosingPanel: PropTypes.bool.isRequired,
swipeEnabled: PropTypes.bool.isRequired,
transactionBag: PropTypes.object,
walletNetwork: PropTypes.string,
walletProviderId: PropTypes.string,
walletWeb3: PropTypes.object,
width: PropTypes.number.isRequired,
wrapper: PropTypes.object,
}

Expand Down Expand Up @@ -115,6 +122,9 @@ class Wrapper extends React.PureComponent {
this.setState({ menuPanelOpened: Boolean(value) })
}
}
handleMenuPanelOpen = () => {
this.setState({ menuPanelOpened: true })
}
handleMenuPanelClose = () => {
this.setState({ menuPanelOpened: false })
}
Expand Down Expand Up @@ -159,41 +169,53 @@ class Wrapper extends React.PureComponent {
locator,
onRequestAppsReload,
onRequestEnable,
swipeEnabled,
transactionBag,
walletNetwork,
walletProviderId,
walletWeb3,
width,
} = this.props
const { menuPanelOpened, notifications, notificationOpen } = this.state

return (
<Main>
<BannerWrapper>{banner}</BannerWrapper>
<Container>
<MenuPanel
apps={apps.filter(app => app.hasWebApp)}
appsStatus={appsStatus}
activeInstanceId={locator.instanceId}
connected={connected}
notifications={notifications.length}
daoAddress={daoAddress}
opened={menuPanelOpened}
autoClosing={autoClosingPanel}
onOpenApp={this.openApp}
onCloseMenuPanel={this.handleMenuPanelClose}
onRequestAppsReload={onRequestAppsReload}
onNotificationClicked={this.handleNotificationClicked}
notificationOpen={notificationOpen}
/>
<AppScreen>
<NotificationBar
open={notificationOpen}
notifications={notifications}
onClearAll={this.handleNotificationsCleared}
/>
{this.renderApp(locator.instanceId, locator.params)}
</AppScreen>
</Container>
<SwipeContainer
enabled={swipeEnabled}
menuPanelOpened={menuPanelOpened}
onMenuPanelClose={this.handleMenuPanelClose}
onMenuPanelOpen={this.handleMenuPanelOpen}
width={width}
>
{progress => (
<React.Fragment>
<MenuPanel
apps={apps.filter(app => app.hasWebApp)}
appsStatus={appsStatus}
activeInstanceId={locator.instanceId}
connected={connected}
notifications={notifications.length}
daoAddress={daoAddress}
openProgress={progress}
autoClosing={autoClosingPanel}
onOpenApp={this.openApp}
onCloseMenuPanel={this.handleMenuPanelClose}
onRequestAppsReload={onRequestAppsReload}
onNotificationClicked={this.handleNotificationClicked}
notificationOpen={notificationOpen}
/>
<AppScreen>
<NotificationBar
open={notificationOpen}
notifications={notifications}
onClearAll={this.handleNotificationsCleared}
/>
{this.renderApp(locator.instanceId, locator.params)}
</AppScreen>
</React.Fragment>
)}
</SwipeContainer>
<SignerPanel
account={account}
apps={apps}
Expand Down Expand Up @@ -315,6 +337,102 @@ class Wrapper extends React.PureComponent {
}
}

const SwipeContainer = (() => {
let _progress = 0

const SwipeContainer = ({
children,
enabled,
menuPanelOpened,
onMenuPanelClose,
onMenuPanelOpen,
width,
}) => {
const oneThirdWindowWidth = width / 3

if (!enabled) {
return <Container>{children(Number(menuPanelOpened))}</Container>
}

return (
<Gesture passive={{ passive: true }}>
{({
delta: [xDelta, yDelta],
direction: [xDir, yDir],
down,
event,
initial: [xInitial],
xy: [x],
}) => {
if (!down && _progress > 0 && _progress < 1) {
_progress = !menuPanelOpened
? _progress > THRESHOLD_PROGRESS
? 1
: 0
: _progress < THRESHOLD_PROGRESS
? 0
: 1
if (_progress === 1) {
setTimeout(() => {
_progress = 0
onMenuPanelOpen()
}, 1)
}
if (_progress === 0) {
setTimeout(() => {
onMenuPanelClose()
}, 1)
}
return <Container>{children(_progress)}</Container>
}

let progress = _progress || Number(menuPanelOpened)

if (
(progress > 0 && progress < 1) ||
(down &&
xDelta &&
yDelta > -THRESHOLD_DISTANCE &&
yDelta < THRESHOLD_DISTANCE &&
xDir &&
yDir > -THRESHOLD_DIRECTION &&
yDir < THRESHOLD_DIRECTION)
) {
event.preventDefault()
if (
xDelta > 0 &&
!menuPanelOpened &&
xInitial < oneThirdWindowWidth
) {
// opening
progress = _progress = Math.max(0, Math.min(1, x / width))
} else if (menuPanelOpened) {
// closing
progress = _progress = Math.max(
0,
Math.min(1, 1 + xDelta / width)
)
}
}

return <Container>{children(progress)}</Container>
}}
</Gesture>
)
}

SwipeContainer.propTypes = {
children: PropTypes.func.isRequired,
enabled: PropTypes.bool.isRequired,
menuPanelOpened: PropTypes.bool.isRequired,
onMenuPanelClose: PropTypes.func.isRequired,
onMenuPanelOpen: PropTypes.func.isRequired,
width: PropTypes.number.isRequired,
}

return SwipeContainer
})()

const Main = styled.div`
display: flex;
flex-direction: column;
Expand Down Expand Up @@ -364,6 +482,13 @@ const LoadingApps = () => (

export default props => (
<Viewport>
{({ below }) => <Wrapper {...props} autoClosingPanel={below('medium')} />}
{({ below, width }) => (
<Wrapper
{...props}
autoClosingPanel={below('medium')}
swipeEnabled={below('medium')}
width={width}
/>
)}
</Viewport>
)

0 comments on commit 1df8dad

Please sign in to comment.