6fbea0a59e
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
272 lines
7.3 KiB
JavaScript
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)
|