Added WIP for new News page Panels
• Added: - WIP for new News page Panels: GabNewsPanel, LatestFromGabPanel, PopularLinks, TrendsFeedsPanel, TrendsHeadlinesPanel - all imports for above in async_components • Todo: - Remove tests
This commit is contained in:
parent
a4ee21282d
commit
4c4894ac5e
|
@ -0,0 +1,90 @@
|
|||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { connect } from 'react-redux'
|
||||
import { injectIntl, defineMessages } from 'react-intl'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||
import { fetchGabNews } from '../../actions/news'
|
||||
import PanelLayout from './panel_layout'
|
||||
import NewsItem from '../news_item'
|
||||
|
||||
class GabNewsPanel extends ImmutablePureComponent {
|
||||
|
||||
state = {
|
||||
fetched: false,
|
||||
}
|
||||
|
||||
static getDerivedStateFromProps(nextProps, prevState) {
|
||||
if (nextProps.shouldLoad && !prevState.fetched) {
|
||||
return { fetched: true }
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
if (!prevState.fetched && this.state.fetched && this.props.isLazy) {
|
||||
this.props.dispatch(fetchGabNews())
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (!this.props.isLazy) {
|
||||
this.props.dispatch(fetchGabNews())
|
||||
this.setState({ fetched: true })
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
intl,
|
||||
isLoading,
|
||||
items,
|
||||
} = this.props
|
||||
const { fetched } = this.state
|
||||
|
||||
const count = !!items ? items.count() : 0
|
||||
if (count === 0 && fetched) return null
|
||||
|
||||
return (
|
||||
<PanelLayout
|
||||
noPadding
|
||||
title={intl.formatMessage(messages.title)}
|
||||
headerButtonTitle={intl.formatMessage(messages.readMore)}
|
||||
headerButtonHref='https://news.gab.com'
|
||||
footerButtonTitle={intl.formatMessage(messages.readMore)}
|
||||
footerButtonHref='https://news.gab.com'
|
||||
>
|
||||
<div className={[_s.d, _s.borderTop1PX, _s.borderBottom1PX, _s.borderColorSecondary, _s.flexRow, _s.w100PC, _s.overflowXScroll, _s.py15, _s.pl15].join(' ')}>
|
||||
{
|
||||
count > 0 &&
|
||||
items.slice(0, 5).map((news, i) => (
|
||||
<NewsItem news={news} key={`news-panel-item-${i}`} />
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</PanelLayout>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const messages = defineMessages({
|
||||
title: { id: 'gab_news.title', defaultMessage: 'Gab News' },
|
||||
readMore: { id: 'status.read_more', defaultMessage: 'Read more' },
|
||||
})
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
isLoading: state.getIn(['news', 'gab_news', 'isLoading']),
|
||||
isFetched: state.getIn(['news', 'gab_news', 'isFetched']),
|
||||
items: state.getIn(['news', 'gab_news', 'items']),
|
||||
})
|
||||
|
||||
GabNewsPanel.propTypes = {
|
||||
intl: PropTypes.object.isRequired,
|
||||
isLazy: PropTypes.bool,
|
||||
isLoading: PropTypes.bool,
|
||||
isFetched: PropTypes.bool,
|
||||
items: ImmutablePropTypes.list.isRequired,
|
||||
}
|
||||
|
||||
export default injectIntl(connect(mapStateToProps)(GabNewsPanel))
|
|
@ -0,0 +1,77 @@
|
|||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { connect } from 'react-redux'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||
import { fetchLatestFromGabTimeline } from '../../actions/news'
|
||||
import PanelLayout from './panel_layout'
|
||||
import StatusContainer from '../../containers/status_container'
|
||||
|
||||
class LatestFromGabPanel extends ImmutablePureComponent {
|
||||
|
||||
state = {
|
||||
fetched: false,
|
||||
}
|
||||
|
||||
static getDerivedStateFromProps(nextProps, prevState) {
|
||||
if (nextProps.shouldLoad && !prevState.fetched) {
|
||||
return { fetched: true }
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
if (!prevState.fetched && this.state.fetched && this.props.isLazy) {
|
||||
this.props.dispatch(fetchLatestFromGabTimeline())
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (!this.props.isLazy) {
|
||||
this.props.dispatch(fetchLatestFromGabTimeline())
|
||||
this.setState({ fetched: true })
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { items } = this.props
|
||||
const { fetched } = this.state
|
||||
|
||||
const count = !!items ? items.count() : 0
|
||||
if (count === 0 && fetched) return null
|
||||
|
||||
return (
|
||||
<PanelLayout
|
||||
noPadding
|
||||
title='Latest from @Gab'
|
||||
headerButtonTo='/gab'
|
||||
headerButtonTitle='Go to @gab'
|
||||
>
|
||||
{
|
||||
items.map((statusId, i) => (
|
||||
<div
|
||||
className={[_s.d, _s.w100PC, _s.px15, _s.pt5, _s.pb10].join(' ')}
|
||||
key={`latest-from-gab-status-${i}`}
|
||||
>
|
||||
<StatusContainer
|
||||
id={statusId}
|
||||
isChild
|
||||
/>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</PanelLayout>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
items: state.getIn(['news', 'latest_from_gab', 'items']),
|
||||
})
|
||||
|
||||
LatestFromGabPanel.propTypes = {
|
||||
//
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(LatestFromGabPanel)
|
|
@ -0,0 +1,79 @@
|
|||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { connect } from 'react-redux'
|
||||
import { fetchPopularLinks } from '../../actions/links'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||
import PanelLayout from './panel_layout'
|
||||
import PreviewCardItem from '../preview_card_item'
|
||||
|
||||
class PopularLinksPanel extends ImmutablePureComponent {
|
||||
|
||||
state = {
|
||||
fetched: false,
|
||||
}
|
||||
|
||||
static getDerivedStateFromProps(nextProps, prevState) {
|
||||
if (nextProps.shouldLoad && !prevState.fetched) {
|
||||
return { fetched: true }
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
if (!prevState.fetched && this.state.fetched && this.props.isLazy) {
|
||||
this.props.dispatch(fetchPopularLinks())
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (!this.props.isLazy) {
|
||||
this.props.dispatch(fetchPopularLinks())
|
||||
this.setState({ fetched: true })
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
intl,
|
||||
popularLinksIsLoading,
|
||||
popularLinksItems,
|
||||
} = this.props
|
||||
const { fetched } = this.state
|
||||
|
||||
const count = !!popularLinksItems ? popularLinksItems.count() : 0
|
||||
// : TESTING :
|
||||
// if (count === 0 && fetched) return null
|
||||
|
||||
return (
|
||||
<PanelLayout
|
||||
title='Trending Links on Gab'
|
||||
subtitle='Most popular links on Gab in last 15 minutes'
|
||||
>
|
||||
<div className={[_s.d, _s.w100PC].join(' ')}>
|
||||
{ /*
|
||||
popularLinksItems.map((id, i) => (
|
||||
<PreviewCardItem id={id} key={`preview-card-${id}-${i}`} />
|
||||
))
|
||||
*/ }
|
||||
<PreviewCardItem id={'144'} />
|
||||
<PreviewCardItem id={'144'} />
|
||||
<PreviewCardItem id={'144'} />
|
||||
</div>
|
||||
</PanelLayout>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
popularLinksIsLoading: state.getIn(['links', 'popular', 'isLoading']),
|
||||
popularLinksItems: state.getIn(['links', 'popular', 'items']),
|
||||
})
|
||||
|
||||
PopularLinksPanel.propTypes = {
|
||||
popularLinksIsLoading: PropTypes.bool.isRequired,
|
||||
popularLinksItems: ImmutablePropTypes.list.isRequired,
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(PopularLinksPanel)
|
|
@ -0,0 +1,43 @@
|
|||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { connect } from 'react-redux'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||
import { TRENDS_RSS_SOURCES } from '../../constants'
|
||||
import PanelLayout from './panel_layout'
|
||||
import Button from '../button'
|
||||
import Text from '../text'
|
||||
|
||||
class TrendsFeedsPanel extends ImmutablePureComponent {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<PanelLayout
|
||||
title='All News Feeds'
|
||||
subtitle='Click on each one to see a feed of each'
|
||||
>
|
||||
<div className={[_s.d, _s.flexRow, _s.flexWrap].join(' ')}>
|
||||
{
|
||||
TRENDS_RSS_SOURCES.map((block, i) => (
|
||||
<Button
|
||||
isNarrow
|
||||
to={`/news/view/${block.id}`}
|
||||
color='primary'
|
||||
backgroundColor='tertiary'
|
||||
className={[_s.mr10, _s.mb10].join(' ')}
|
||||
key={`trends-feeds-panel-${i}`}
|
||||
>
|
||||
<Text color='inherit'>
|
||||
{block.title}
|
||||
</Text>
|
||||
</Button>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</PanelLayout>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default TrendsFeedsPanel
|
|
@ -0,0 +1,97 @@
|
|||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { connect } from 'react-redux'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||
import { CX } from '../../constants'
|
||||
import PanelLayout from './panel_layout'
|
||||
import Button from '../button'
|
||||
import Text from '../text'
|
||||
import Image from '../image'
|
||||
|
||||
// depends on TrendsBreakingPanel atm.
|
||||
class TrendsHeadlinesPanel extends ImmutablePureComponent {
|
||||
|
||||
render() {
|
||||
const {
|
||||
isFetched,
|
||||
isLoading,
|
||||
items,
|
||||
trendsLeadline,
|
||||
} = this.props
|
||||
|
||||
const count = !!items ? items.count() : 0
|
||||
const trendsLeadlineTitle = trendsLeadline.get('title')
|
||||
const trendsLeadlineImage = trendsLeadline.get('image')
|
||||
const trendsLeadlineUrl = trendsLeadline.get('trends_url')
|
||||
|
||||
if ((count === 0 && isFetched) && (!trendsLeadlineTitle || !trendsLeadlineTitle || !trendsLeadlineTitle)) return null
|
||||
|
||||
const leadlineButtonClasses = CX({
|
||||
d: 1,
|
||||
cursorPointer: 1,
|
||||
noUnderline: 1,
|
||||
bgPrimary: 1,
|
||||
w100PC: 1,
|
||||
border1PX: 1,
|
||||
borderColorSecondary: 1,
|
||||
radiusSmall: 1,
|
||||
overflowHidden: 1,
|
||||
bgSubtle_onHover: 1,
|
||||
mb5: 1,
|
||||
mt10: count > 0,
|
||||
})
|
||||
|
||||
return (
|
||||
<PanelLayout
|
||||
title='Headlines'
|
||||
subtitle='Headlines about yadda'
|
||||
>
|
||||
{
|
||||
count > 0 &&
|
||||
items.slice(0, 5).map((headline, i) => (
|
||||
<Button
|
||||
isText
|
||||
backgroundColor='none'
|
||||
color='primary'
|
||||
className={[_s.d, _s.pb15].join(' ')}
|
||||
href={headline.get('trends_url')}
|
||||
key={`headline-news-item-${i}`}
|
||||
>
|
||||
<Text color='inherit' size='small'>
|
||||
{headline.get('title')}
|
||||
</Text>
|
||||
</Button>
|
||||
))
|
||||
}
|
||||
<Button
|
||||
noClasses
|
||||
href={''}
|
||||
className={leadlineButtonClasses}
|
||||
>
|
||||
<Image
|
||||
src='https://trends.gab.com/image/5fa5d8badf30e602384b08ed'
|
||||
/>
|
||||
<Text className={[_s.px15, _s.py15, _s.w100PC, _s.borderTop1PX, _s.borderColorSecondary].join(' ')}>
|
||||
Lawsuit: At Least 21K Dead People on Pennsylvania Voter Rolls
|
||||
</Text>
|
||||
</Button>
|
||||
</PanelLayout>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
isLoading: state.getIn(['news', 'trends_headlines', 'isLoading']),
|
||||
isFetched: state.getIn(['news', 'trends_headlines', 'isFetched']),
|
||||
items: state.getIn(['news', 'trends_headlines', 'items']),
|
||||
trendsLeadline: state.getIn(['news', 'trends_leadline']),
|
||||
})
|
||||
|
||||
TrendsHeadlinesPanel.propTypes = {
|
||||
isLoading: PropTypes.bool,
|
||||
isFetched: PropTypes.bool,
|
||||
items: ImmutablePropTypes.list.isRequired,
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(TrendsHeadlinesPanel)
|
|
@ -29,6 +29,7 @@ export function Followers() { return import(/* webpackChunkName: "features/follo
|
|||
export function Following() { return import(/* webpackChunkName: "features/following" */'../../following') }
|
||||
export function FollowRequests() { return import(/* webpackChunkName: "features/follow_requests" */'../../follow_requests') }
|
||||
export function LikedStatuses() { return import(/* webpackChunkName: "features/liked_statuses" */'../../liked_statuses') }
|
||||
export function GabNewsPanel() { return import(/* webpackChunkName: "components/gab_news_panel" */'../../../components/panel/gab_news_panel') }
|
||||
export function GenericNotFound() { return import(/* webpackChunkName: "features/generic_not_found" */'../../generic_not_found') }
|
||||
export function GlobalFooter() { return import(/* webpackChunkName: "components/global_footer" */'../../../components/global_footer') }
|
||||
export function GroupCategoriesInjection() { return import(/* webpackChunkName: "components/group_categories_injection" */'../../../components/timeline_injections/group_categories_injection') }
|
||||
|
@ -60,6 +61,7 @@ export function HomeTimelineSettingsModal() { return import(/* webpackChunkName:
|
|||
export function HotkeysModal() { return import(/* webpackChunkName: "components/hotkeys_modal" */'../../../components/modal/hotkeys_modal') }
|
||||
export function Introduction() { return import(/* webpackChunkName: "features/introduction" */'../../introduction') }
|
||||
export function Investors() { return import(/* webpackChunkName: "features/about/investors" */'../../about/investors') }
|
||||
export function LatestFromGabPanel() { return import(/* webpackChunkName: "components/latest_from_gab_panel" */'../../../components/panel/latest_from_gab_panel') }
|
||||
export function LinkFooter() { return import(/* webpackChunkName: "components/link_footer" */'../../../components/link_footer') }
|
||||
export function LinkTimeline() { return import(/* webpackChunkName: "features/link_timeline" */'../../link_timeline') }
|
||||
export function ListAddUserModal() { return import(/* webpackChunkName: "features/list_add_user_modal" */'../../../components/modal/list_add_user_modal') }
|
||||
|
@ -76,12 +78,15 @@ export function ListTimelineSettingsModal() { return import(/* webpackChunkName:
|
|||
export function MediaGallery() { return import(/* webpackChunkName: "components/media_gallery" */'../../../components/media_gallery') }
|
||||
export function MediaGalleryPanel() { return import(/* webpackChunkName: "components/media_gallery_panel" */'../../../components/panel/media_gallery_panel') }
|
||||
export function MediaModal() { return import(/* webpackChunkName: "components/media_modal" */'../../../components/modal/media_modal') }
|
||||
export function Messages() { return import(/* webpackChunkName: "features/messages" */'../../messages') }
|
||||
export function Mutes() { return import(/* webpackChunkName: "features/mutes" */'../../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 News() { return import(/* webpackChunkName: "features/news" */'../../news') }
|
||||
export function NewsView() { return import(/* webpackChunkName: "features/news_view" */'../../news_view') }
|
||||
export function Notifications() { return import(/* webpackChunkName: "features/notifications" */'../../notifications') }
|
||||
export function NotificationFilterPanel() { return import(/* webpackChunkName: "components/notification_filter_panel" */'../../../components/panel/notification_filter_panel') }
|
||||
export function PopularLinksPanel() { return import(/* webpackChunkName: "components/popular_links_panel" */'../../../components/panel/popular_links_panel') }
|
||||
export function Press() { return import(/* webpackChunkName: "features/about/press" */'../../about/press') }
|
||||
export function PrivacyPolicy() { return import(/* webpackChunkName: "features/about/privacy_policy" */'../../about/privacy_policy') }
|
||||
export function ProTimeline() { return import(/* webpackChunkName: "features/pro_timeline" */'../../pro_timeline') }
|
||||
|
@ -120,7 +125,10 @@ export function Suggestions() { return import(/* webpackChunkName: "features/sug
|
|||
export function TermsOfSale() { return import(/* webpackChunkName: "features/about/terms_of_sale" */'../../about/terms_of_sale') }
|
||||
export function TermsOfService() { return import(/* webpackChunkName: "features/about/terms_of_service" */'../../about/terms_of_service') }
|
||||
export function TimelineInjectionOptionsPopover() { return import(/* webpackChunkName: "components/timeline_injection_options_popover" */'../../../components/popover/timeline_injection_options_popover') }
|
||||
export function TrendsPanel() { return import(/* webpackChunkName: "components/trends_panel" */'../../../components/panel/trends_panel') }
|
||||
export function TrendsBreakingPanel() { return import(/* webpackChunkName: "components/trends_breaking_panel" */'../../../components/panel/trends_breaking_panel') }
|
||||
export function TrendsFeedsPanel() { return import(/* webpackChunkName: "components/trends_feeds_panel" */'../../../components/panel/trends_feeds_panel') }
|
||||
export function TrendsHeadlinesPanel() { return import(/* webpackChunkName: "components/trends_headlines_panel" */'../../../components/panel/trends_headlines_panel') }
|
||||
export function TrendsRSSPanel() { return import(/* webpackChunkName: "components/trends_headlines_panel" */'../../../components/panel/trends_rss_panel') }
|
||||
export function UnauthorizedModal() { return import(/* webpackChunkName: "components/unauthorized_modal" */'../../../components/modal/unauthorized_modal') }
|
||||
export function UnfollowModal() { return import(/* webpackChunkName: "components/unfollow_modal" */'../../../components/modal/unfollow_modal') }
|
||||
export function UserInfoPopover() { return import(/* webpackChunkName: "components/user_info_popover" */'../../../components/popover/user_info_popover') }
|
||||
|
|
Loading…
Reference in New Issue