Added pro feed

• Added:
- pro feed
This commit is contained in:
mgabdev
2020-07-01 21:40:00 -04:00
parent 7410c4c6ab
commit bc2eeee497
15 changed files with 230 additions and 9 deletions

View File

@@ -51,6 +51,7 @@ export function connectTimelineStream (timelineId, path, pollingRefresh = null,
}
export const connectUserStream = () => connectTimelineStream('home', 'user');
export const connectProStream = () => connectTimelineStream('pro', 'pro');
export const connectHashtagStream = (id, tag, accept) => connectTimelineStream(`hashtag:${id}`, `hashtag&tag=${tag}`, null, accept);
export const connectListStream = id => connectTimelineStream(`list:${id}`, `list&list=${id}`);
export const connectGroupStream = id => connectTimelineStream(`group:${id}`, `group&group=${id}`);

View File

@@ -166,6 +166,7 @@ export function expandTimeline(timelineId, path, params = {}, done = noOp) {
};
export const expandHomeTimeline = ({ maxId } = {}, done = noOp) => expandTimeline('home', '/api/v1/timelines/home', { max_id: maxId }, done);
export const expandProTimeline = ({ maxId } = {}, done = noOp) => expandTimeline('pro', '/api/v1/timelines/pro', { max_id: maxId }, done);
export const expandCommunityTimeline = ({ maxId, onlyMedia } = {}, done = noOp) => expandTimeline(`community${onlyMedia ? ':media' : ''}`, '/api/v1/timelines/public', { max_id: maxId, only_media: !!onlyMedia }, done);
export const expandAccountTimeline = (accountId, { maxId, withReplies, commentsOnly } = {}) => expandTimeline(`account:${accountId}${withReplies ? ':with_replies' : ''}${commentsOnly ? ':comments_only' : ''}`, `/api/v1/accounts/${accountId}/statuses`, { only_comments: commentsOnly, exclude_replies: (!withReplies && !commentsOnly), max_id: maxId });
export const expandAccountFeaturedTimeline = accountId => expandTimeline(`account:${accountId}:pinned`, `/api/v1/accounts/${accountId}/statuses`, { pinned: true });

View File

@@ -164,6 +164,11 @@ class Sidebar extends ImmutablePureComponent {
]
const exploreItems = [
{
title: 'Pro Feed',
icon: 'circle',
to: '/timeline/pro',
},
{
title: 'Chat',
icon: 'chat',

View File

@@ -39,6 +39,7 @@ const messages = defineMessages({
chat: { id: 'tabs_bar.chat', defaultMessage: 'Chat' },
help: { id: 'getting_started.help', defaultMessage: 'Help' },
display: { id: 'display_options', defaultMessage: 'Display Options' },
pro: { id: 'pro_feed', defaultMessage: 'Pro Feed' },
})
const mapStateToProps = (state) => ({
@@ -94,6 +95,12 @@ class SidebarXS extends ImmutablePureComponent {
onClick: this.handleSidebarClose,
title: intl.formatMessage(messages.profile),
},
{
icon: 'list',
to: '/lists',
onClick: this.handleSidebarClose,
title: intl.formatMessage(messages.lists),
},
{
icon: 'pro',
href: 'https://pro.gab.com',
@@ -124,18 +131,18 @@ class SidebarXS extends ImmutablePureComponent {
onClick: this.handleSidebarClose,
title: intl.formatMessage(messages.search),
},
{
icon: 'circle',
to: '/timeline/pro',
onClick: this.handleSidebarClose,
title: intl.formatMessage(messages.pro),
},
{
icon: 'cog',
href: '/settings/preferences',
onClick: this.handleSidebarClose,
title: intl.formatMessage(messages.preferences),
},
{
icon: 'list',
to: '/lists',
onClick: this.handleSidebarClose,
title: intl.formatMessage(messages.lists),
},
// {
// icon: 'group',
// to: '/follow_requests',

View File

@@ -0,0 +1,60 @@
import { defineMessages, injectIntl } from 'react-intl'
import { expandProTimeline } from '../actions/timelines'
import { connectProStream } from '../actions/streaming'
import StatusList from '../components/status_list'
const messages = defineMessages({
empty: { id: 'empty_column.pro', defaultMessage: 'The pro timeline is empty.' },
})
export default
@injectIntl
@connect(null)
class ProTimeline extends PureComponent {
static contextTypes = {
router: PropTypes.object,
}
static propTypes = {
dispatch: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
}
componentDidMount () {
const { dispatch } = this.props
dispatch(expandProTimeline())
this.disconnect = dispatch(connectProStream())
}
componentWillUnmount() {
if (this.disconnect) {
this.disconnect()
this.disconnect = null
}
}
handleLoadMore = (maxId) => {
const { dispatch } = this.props
dispatch(expandProTimeline({ maxId }))
}
render () {
const { intl } = this.props
const emptyMessage = intl.formatMessage(messages.empty)
return (
<StatusList
scrollKey='pro_timeline'
timelineId='pro'
onLoadMore={this.handleLoadMore}
emptyMessage={emptyMessage}
/>
)
}
}

View File

@@ -36,6 +36,7 @@ import ListsPage from '../../pages/lists_page'
import BasicPage from '../../pages/basic_page'
import ModalPage from '../../pages/modal_page'
import SettingsPage from '../../pages/settings_page'
import ProPage from '../../pages/pro_page'
import {
AccountGallery,
@@ -64,6 +65,7 @@ import {
ListTimeline,
Mutes,
Notifications,
ProTimeline,
Search,
// Shortcuts,
StatusFeature,
@@ -151,6 +153,7 @@ class SwitchingArea extends PureComponent {
<WrappedRoute path='/compose' exact page={BasicPage} component={Compose} content={children} componentParams={{ title: 'Compose' }} />
<WrappedRoute path='/timeline/all' exact page={CommunityPage} component={CommunityTimeline} content={children} componentParams={{ title: 'Community Feed' }} />
<WrappedRoute path='/timeline/pro' exact page={ProPage} component={ProTimeline} content={children} componentParams={{ title: 'Pro Feed' }} />
<WrappedRoute path='/groups' exact page={GroupsPage} component={GroupsCollection} content={children} componentParams={{ activeTab: 'featured' }} />
<WrappedRoute path='/groups/new' exact page={GroupsPage} component={GroupsCollection} content={children} componentParams={{ activeTab: 'new' }} />

View File

@@ -55,6 +55,7 @@ export function Mutes() { return import(/* webpackChunkName: "features/mutes" */
export function MuteModal() { return import(/* webpackChunkName: "modals/mute_modal" */'../../../components/modal/mute_modal') }
export function NavSettingsPopover() { return import(/* webpackChunkName: "modals/nav_settings_popover" */'../../../components/popover/nav_settings_popover') }
export function Notifications() { return import(/* webpackChunkName: "features/notifications" */'../../notifications') }
export function ProTimeline() { return import(/* webpackChunkName: "features/pro_timeline" */'../../pro_timeline') }
export function ProfileOptionsPopover() { return import(/* webpackChunkName: "components/profile_options_popover" */'../../../components/popover/profile_options_popover') }
export function ProUpgradeModal() { return import(/* webpackChunkName: "components/pro_upgrade_modal" */'../../../components/modal/pro_upgrade_modal') }
export function ReportModal() { return import(/* webpackChunkName: "modals/report_modal" */'../../../components/modal/report_modal') }

View File

@@ -0,0 +1,43 @@
import { Fragment } from 'react'
import { defineMessages, injectIntl } from 'react-intl'
import PageTitle from '../features/ui/util/page_title'
import LinkFooter from '../components/link_footer'
import VerifiedAccountsPanel from '../components/panel/verified_accounts_panel'
import ProgressPanel from '../components/panel/progress_panel'
import DefaultLayout from '../layouts/default_layout'
const messages = defineMessages({
title: { 'id': 'column.pro', 'defaultMessage': 'Pro feed' },
})
export default
@injectIntl
class ProPage extends PureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
children: PropTypes.node.isRequired,
}
render() {
const { intl, children } = this.props
const title = intl.formatMessage(messages.title)
return (
<DefaultLayout
title={title}
layout={(
<Fragment>
<ProgressPanel />
<VerifiedAccountsPanel />
<LinkFooter />
</Fragment>
)}
>
<PageTitle path={title} />
{children}
</DefaultLayout>
)
}
}