gab-social/app/javascript/gabsocial/features/deck.js
mgabdev 6fbea0a59e Progress on little important things
removing .mov for now until we can figure out solution with videojs, added model to track username changes, got chat creation flow down, progress on bookmark collections, albums, filtering blocks/mutes from group, explore, collection timelines
2020-12-22 01:36:38 -05:00

272 lines
7.3 KiB
JavaScript

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,
GroupTimeline,
LikedStatuses,
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) => {
if (!deckColumn || !this.props.isPro) return null
let Component, noRefresh, accountId, icon = null
let componentParams = {}
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
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) {
const userAccountId = deckColumn.replace('user.', '')
title = 'User'
Component = AccountTimeline
componentParams = { id: userAccountId }
accountId = userAccountId
} else if (deckColumn.indexOf('list.') > -1) {
const listId = deckColumn.replace('list.', '')
title = 'List'
subtitle = listId
icon = 'list'
Component = ListTimeline
componentParams = { params: { id: listId }}
} else if (deckColumn.indexOf('group.') > -1) {
const groupId = deckColumn.replace('group.', '')
title = 'Group'
subtitle = groupId
icon = 'group'
Component = GroupTimeline
componentParams = { params: { id: groupId }}
} else if (deckColumn.indexOf('news.') > -1) {
// : todo :
} else if (deckColumn.indexOf('hashtag.') > -1) {
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}
>
<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 &&
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)