gab-social/app/javascript/gabsocial/features/deck.js

272 lines
7.3 KiB
JavaScript
Raw Normal View History

import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import ImmutablePropTypes from 'react-immutable-proptypes'
import ImmutablePureComponent from 'react-immutable-pure-component'
import {
sortableContainer,
sortableElement,
} from 'react-sortable-hoc'
import { me, meUsername} from '../initial_state'
import {
GAB_DECK_MAX_ITEMS,
URL_GAB_PRO,
MODAL_PRO_UPGRADE,
} from '../constants'
import {
deckConnect,
deckDisconnect,
updateDeckColumnAtIndex,
} from '../actions/deck'
import { saveSettings } from '../actions/settings'
import { openModal } from '../actions/modal'
import WrappedBundle from './ui/util/wrapped_bundle'
import DeckColumn from '../components/deck_column'
import Text from '../components/text'
import Button from '../components/button'
import {
AccountTimeline,
Compose,
2020-12-16 07:39:07 +00:00
GroupTimeline,
LikedStatuses,
2020-12-16 07:39:07 +00:00
ListTimeline,
HomeTimeline,
Notifications,
HashtagTimeline,
BookmarkedStatuses,
ProTimeline,
News,
ExploreTimeline,
} from './ui/util/async_components'
class Deck extends React.PureComponent {
static contextTypes = {
router: PropTypes.object,
}
componentDidMount () {
this.props.dispatch(deckConnect())
if (!this.props.isPro) this.handleOnOpenProUpgradeModal()
}
componentWillUnmount() {
this.props.dispatch(deckDisconnect())
}
handleOnOpenProUpgradeModal = () => {
this.props.dispatch(openModal(MODAL_PRO_UPGRADE))
}
onSortEnd = ({oldIndex, newIndex}) => {
this.props.dispatch(updateDeckColumnAtIndex(oldIndex, newIndex))
}
onShouldCancelStart = (event) => {
if (event.target) {
if (!event.target.hasAttribute('data-sort-header')) {
return true
}
}
return false
}
getDeckColumn = (deckColumn, index) => {
2020-12-09 20:02:43 +00:00
if (!deckColumn || !this.props.isPro) return null
2020-12-16 22:29:06 +00:00
let Component, noRefresh, accountId, icon = null
let componentParams = {}
2020-12-16 22:29:06 +00:00
let title, subtitle = ''
switch (deckColumn) {
case 'notifications':
title = 'Notifications'
icon = 'notifications'
Component = Notifications
break
case 'home':
title = 'Home'
icon = 'home'
Component = HomeTimeline
break
case 'compose':
title = 'Compose'
icon = 'pencil'
Component = Compose
2020-12-16 22:29:06 +00:00
noRefresh = true
break
case 'likes':
title = 'Likes'
icon = 'like'
Component = LikedStatuses
componentParams = { params: { username: meUsername }}
break
case 'bookmarks':
title = 'Bookmarks'
icon = 'bookmark'
Component = BookmarkedStatuses
componentParams = { params: { username: meUsername }}
break
case 'pro':
title = 'Pro Timeline'
icon = 'pro'
Component = ProTimeline
break
case 'news':
title = 'News'
icon = 'news'
Component = News
componentParams = { isSmall: true }
break
case 'explore':
title = 'Explore'
icon = 'explore'
Component = ExploreTimeline
break
default:
break
}
if (!Component) {
if (deckColumn.indexOf('user.') > -1) {
2020-12-16 22:29:06 +00:00
const userAccountId = deckColumn.replace('user.', '')
title = 'User'
Component = AccountTimeline
componentParams = { id: userAccountId }
accountId = userAccountId
} else if (deckColumn.indexOf('list.') > -1) {
2020-12-16 07:39:07 +00:00
const listId = deckColumn.replace('list.', '')
title = 'List'
subtitle = listId
icon = 'list'
Component = ListTimeline
componentParams = { params: { id: listId }}
} else if (deckColumn.indexOf('group.') > -1) {
2020-12-16 07:39:07 +00:00
const groupId = deckColumn.replace('group.', '')
title = 'Group'
subtitle = groupId
icon = 'group'
Component = GroupTimeline
componentParams = { params: { id: groupId }}
} else if (deckColumn.indexOf('news.') > -1) {
2020-12-16 07:39:07 +00:00
// : todo :
} else if (deckColumn.indexOf('hashtag.') > -1) {
2020-12-16 07:39:07 +00:00
const hashtag = deckColumn.replace('hashtag.', '')
title = 'Hashtag'
subtitle = hashtag
icon = 'apps'
Component = HashtagTimeline
componentParams = { params: { id: hashtag }}
}
}
if (!Component) return null
return (
<SortableItem
key={`deck-column-${index}`}
index={index}
sortIndex={index}
>
2020-12-16 22:29:06 +00:00
<DeckColumn
title={title}
subtitle={subtitle}
icon={icon}
index={index}
noRefresh={noRefresh}
accountId={accountId}
>
<WrappedBundle component={Component} componentParams={componentParams} />
</DeckColumn>
</SortableItem>
)
}
render () {
const { gabDeckOrder, isPro } = this.props
const isEmpty = gabDeckOrder.size === 0
const title = (
<span className={[_s.d, _s.flexRow, _s.jcCenter, _s.aiCenter].join(' ')}>
<span className={[_s.d, _s.mr2].join(' ')}>
Gab Deck for Gab
</span>
<span className={[_s.bgPro, _s.cBlack, _s.radiusSmall, _s.px5, _s.py5].join(' ')}>PRO</span>
</span>
)
return (
<SortableContainer
axis='x'
lockAxis='x'
onSortEnd={this.onSortEnd}
shouldCancelStart={this.onShouldCancelStart}
>
{
(isEmpty || !isPro) &&
<React.Fragment>
<DeckColumn title='Compose' icon='pencil' noButtons>
<WrappedBundle component={Compose} />
</DeckColumn>
{
!isPro &&
<DeckColumn title={title} icon='pro' noButtons>
<div className={[_s.d, _s.px15, _s.py15].join(' ')}>
<Text>
GabDeck is a unique way to customize your Gab experience. Upgrade to GabPRO to unlock the GabDeck.
</Text>
<div className={[_s.mt15, _s.d, _s.flexRow].join(' ')}>
<Button href={URL_GAB_PRO}>
<Text color='inherit' className={_s.px10}>
Upgrade to GabPRO
</Text>
</Button>
</div>
</div>
</DeckColumn>
}
<DeckColumn title='Explore' icon='explore' noButtons>
<WrappedBundle component={ExploreTimeline} />
</DeckColumn>
<DeckColumn title='News' icon='news' noButtons>
<WrappedBundle component={News} componentParams={{ isSmall: true }} />
</DeckColumn>
<DeckColumn />
</React.Fragment>
}
{
!isEmpty && isPro &&
2020-12-09 20:02:43 +00:00
gabDeckOrder.map((deckOption, i) => this.getDeckColumn(deckOption, i))
}
</SortableContainer>
)
}
}
const SortableItem = sortableElement(({children}) => (
<div>
{children}
</div>
))
const SortableContainer = sortableContainer(({children}) => (
<div className={[_s.d, _s.flexRow, _s.listStyleNone].join(' ')}>
{children}
</div>
))
const mapStateToProps = (state) => ({
isPro: state.getIn(['accounts', me, 'is_pro']),
gabDeckOrder: state.getIn(['settings', 'gabDeckOrder']),
})
Deck.propTypes = {
isPro: PropTypes.bool.isRequired,
gabDeckOrder: ImmutablePropTypes.list,
}
export default connect(mapStateToProps)(Deck)