Updated NewsView, TrendsHeadlinesPanel, TrendsRSSPanel

• Updated:
- NewsView, TrendsHeadlinesPanel, TrendsRSSPanel
This commit is contained in:
mgabdev 2020-11-09 01:35:59 -06:00
parent b6f8674054
commit bef3ad6fca
5 changed files with 264 additions and 56 deletions

View File

@ -1,6 +1,7 @@
import api from '../api'
import axios from 'axios'
import { importFetchedStatuses } from './importer'
import { TRENDS_RSS_SOURCES } from '../constants'
export const GAB_TRENDS_FETCH_REQUEST = 'GAB_TRENDS_FETCH_REQUEST'
export const GAB_TRENDS_FETCH_SUCCESS = 'GAB_TRENDS_FETCH_SUCCESS'
@ -54,36 +55,40 @@ const fetchGabTrendsFail = (error) => ({
/**
*
*/
export const expandGabTrendsFeed = (feedId, page = 0) => (dispatch, getState) => {
dispatch(expandGabTrendsFeedRequest(feedId, page))
export const expandGabTrendsFeed = (feedId) => (dispatch, getState) => {
if (!feedId) return
const exists = !!TRENDS_RSS_SOURCES.find((block) => block.id === feedId)
if (!exists) return
// const url = `http://trends.gab.com/feed/${feedId}?fmt=json`
api(getState).get(`/api/v1/gab_trends?type=rss`).then((response) => {
const page = getState().getIn(['news', 'trends_feeds', `${feedId}`, 'curPage'], 0) + 1
dispatch(expandGabTrendsFeedRequest(feedId))
// const url = `http://trends.gab.com/feed/${feedId}?fmt=json&p=${page}`
api(getState).get(`/api/v1/gab_trends?type=rss&page=${page}&feedId=${feedId}`).then((response) => {
// axios.get(url).then((response) => {
dispatch(expandGabTrendsFeedSuccess(response.data, feedId, page))
dispatch(expandGabTrendsFeedSuccess(response.data.rssFeedItems, feedId, response.data.pagination.p))
}).catch((error) => {
dispatch(expandGabTrendsFeedFail(error, feedId, page))
dispatch(expandGabTrendsFeedFail(error, feedId))
})
}
const expandGabTrendsFeedRequest = (feedId, page) => ({
const expandGabTrendsFeedRequest = (feedId) => ({
type: GAB_TREND_FEED_EXPAND_REQUEST,
feedId,
page,
})
const expandGabTrendsFeedSuccess = (items, feedId, page) => ({
const expandGabTrendsFeedSuccess = (items, feedId, curPage) => ({
type: GAB_TREND_FEED_EXPAND_SUCCESS,
items,
feedId,
page,
curPage,
})
const expandGabTrendsFeedFail = (error, feedId, page) => ({
const expandGabTrendsFeedFail = (error, feedId) => ({
type: GAB_TREND_FEED_EXPAND_FAIL,
error,
feedId,
page,
})
/**

View File

@ -21,11 +21,11 @@ class TrendsHeadlinesPanel extends ImmutablePureComponent {
} = this.props
const count = !!items ? items.count() : 0
const trendsLeadlineTitle = trendsLeadline.get('title')
const trendsLeadlineImage = trendsLeadline.get('image')
const trendsLeadlineUrl = trendsLeadline.get('trends_url')
const trendsLeadlineTitle = trendsLeadline ? trendsLeadline.get('title') : null
const trendsLeadlineImage = trendsLeadline ? trendsLeadline.get('image') : null
const trendsLeadlineUrl = trendsLeadline ? trendsLeadline.get('trends_url') : null
if ((count === 0 && isFetched) && (!trendsLeadlineTitle || !trendsLeadlineTitle || !trendsLeadlineTitle)) return null
if ((count === 0 && isFetched) && (!trendsLeadlineImage || !trendsLeadlineTitle || !trendsLeadlineTitle)) return null
const leadlineButtonClasses = CX({
d: 1,
@ -64,18 +64,21 @@ class TrendsHeadlinesPanel extends ImmutablePureComponent {
</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>
{
!!trendsLeadlineImage && !!trendsLeadlineTitle && trendsLeadlineUrl &&
<Button
noClasses
href={trendsLeadlineUrl}
className={leadlineButtonClasses}
>
<Image
src={trendsLeadlineImage}
/>
<Text className={[_s.px15, _s.py15, _s.w100PC, _s.borderTop1PX, _s.borderColorSecondary].join(' ')}>
{trendsLeadlineTitle}
</Text>
</Button>
}
</PanelLayout>
)
}
@ -85,7 +88,7 @@ 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']),
trendsLeadline: state.getIn(['news', 'trends_leadline', 'items']),
})
TrendsHeadlinesPanel.propTypes = {

View File

@ -1,33 +1,143 @@
import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { List as ImmutableList } from 'immutable'
import ImmutablePureComponent from 'react-immutable-pure-component'
import ImmutablePropTypes from 'react-immutable-proptypes'
import { expandGabTrendsFeed } from '../../actions/news'
import {
CX,
BREAKPOINT_EXTRA_SMALL,
} from '../../constants'
import { getWindowDimension } from '../../utils/is_mobile'
import PanelLayout from './panel_layout'
import TrendsCard from '../trends_card'
import Button from '../button'
import LoadMore from '../load_more'
import ScrollableList from '../scrollable_list'
const initialState = getWindowDimension()
class TrendsRSSPanel extends ImmutablePureComponent {
state = {
viewType: 0,
fetched: false,
isXS: initialState.width <= BREAKPOINT_EXTRA_SMALL,
}
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) ||
((prevProps.trendsRSSId !== this.props.trendsRSSId) && !!prevProps.trendsRSSId)) {
this.handleOnExpand()
}
}
componentDidMount() {
if (!this.props.isLazy) {
this.handleOnExpand()
this.setState({ fetched: true })
}
this.handleResize()
window.addEventListener('keyup', this.handleKeyUp, false)
window.addEventListener('resize', this.handleResize, false)
}
handleResize = () => {
const { width } = getWindowDimension()
this.setState({ isXS: width <= BREAKPOINT_EXTRA_SMALL })
}
componentWillUnmount() {
window.removeEventListener('keyup', this.handleKeyUp)
window.removeEventListener('resize', this.handleResize, false)
}
onItemViewClick = () => {
this.setState({ viewType: this.state.viewType === 0 ? 1 : 0 })
}
handleOnExpand = () => {
this.props.dispatch(expandGabTrendsFeed(this.props.trendsRSSId))
}
render() {
const {
intl,
onChange,
settings,
trendsRSSId,
isLoading,
isFetched,
items,
hideReadMore,
feed,
} = this.props
const {
fetched,
viewType,
isXS,
} = this.state
const count = !!items ? items.count() : 0
if (count === 0 && fetched) return null
const hasMore = count % 10 === 0
const containerClasses = CX({
d: 1,
w100PC: 1,
flexRow: viewType === 1,
flexWrap: viewType === 1,
})
return (
<PanelLayout>
TrendsRSSPanel
</PanelLayout>
<div className={[_s.d, _s.w100PC].join(' ')}>
<div className={containerClasses} >
<ScrollableList
scrollKey={`trends-rss-panel-${trendsRSSId}`}
onLoadMore={this.handleOnExpand}
hasMore={hasMore}
isLoading={isLoading}
emptyMessage='No feed items found.'
disableInfiniteScroll
>
{
items.map((trend, i) => (
<TrendsCard
isXS={isXS}
trend={trend}
viewType={viewType}
key={`trend-card-rss-${i}`}
/>
))
}
</ScrollableList>
</div>
</div>
)
}
}
const mapStateToProps = (state) => ({
//
const mapStateToProps = (state, { trendsRSSId }) => ({
isLoading: state.getIn(['news', 'trends_feeds', `${trendsRSSId}`, 'isLoading'], false),
isFetched: state.getIn(['news', 'trends_feeds', `${trendsRSSId}`, 'isFetched'], false),
items: state.getIn(['news', 'trends_feeds', `${trendsRSSId}`, 'items'], ImmutableList()),
})
TrendsFeedsPanel.propTypes = {
//
TrendsRSSPanel.propTypes = {
isLazy: PropTypes.bool,
isLoading: PropTypes.bool,
isFetched: PropTypes.bool,
trendsRSSId: PropTypes.string.isRequired,
items: ImmutablePropTypes.list,
isPage: PropTypes.bool,
}
export default connect(mapStateToProps)(TrendsRSSPanel)

View File

@ -4,20 +4,78 @@ import { connect } from 'react-redux'
import { TRENDS_RSS_SOURCES } from '../constants'
import WrappedBundle from './ui/util/wrapped_bundle'
import { TrendsRSSPanel } from './ui/util/async_components'
import Button from '../components/button'
import ColumnIndicator from '../components/column_indicator'
import Text from '../components/text'
class NewsView extends React.PureComponent {
state = {
exists: false,
orderedSources: [],
}
componentDidMount() {
const { params: { trendsRSSId } } = this.props
this.setState({
exists: this.getExists(trendsRSSId),
orderedSources: this.getOrderedSources(trendsRSSId)
})
}
componentDidUpdate(prevProps) {
const { params: { trendsRSSId } } = this.props
if (prevProps.params.trendsRSSId !== trendsRSSId) {
this.setState({
exists: this.getExists(trendsRSSId),
orderedSources: this.getOrderedSources(trendsRSSId),
})
}
}
getExists = (trendsRSSId) => {
return !!TRENDS_RSS_SOURCES.find((source) => source.id === trendsRSSId)
}
getOrderedSources = (trendsRSSId) => {
const source = TRENDS_RSS_SOURCES.find((source) => source.id === trendsRSSId)
const sourceIndex = TRENDS_RSS_SOURCES.findIndex((source) => source.id === trendsRSSId)
if (!source) return []
let orderedSources = TRENDS_RSS_SOURCES.filter((source) => source.id !== trendsRSSId);
const activeSource = { ...source, isActive: 1 }
orderedSources[sourceIndex] = activeSource
orderedSources.unshift(activeSource);
return orderedSources
}
render() {
const { params: { trendsRSSId } } = this.props
console.log("trendsRSSId:", trendsRSSId)
const exists = !!TRENDS_RSS_SOURCES.find((block) => block.id === trendsRSSId)
const { orderedSources, exists } = this.state
if (!exists) return <ColumnIndicator type='missing' />
return (
<div className={[_s.d, _s.w100PC].join(' ')}>
<WrappedBundle component={TrendsRSSPanel} />
<div className={[_s.d, _s.flexRow, _s.w100PC, _s.overflowXScroll, _s.py10, _s.px10, _s.mb5].join(' ')}>
{
orderedSources.map((block, i) => (
<Button
isNarrow
to={block.isActive ? undefined : `/news/view/${block.id}`}
color={block.isActive ? 'white' : 'primary'}
backgroundColor={block.isActive ? 'brand' : 'tertiary'}
className={[_s.mr10, _s.mb10].join(' ')}
key={`trends-feeds-panel-${i}`}
>
<Text color='inherit'>
{block.title}
</Text>
</Button>
))
}
</div>
<WrappedBundle component={TrendsRSSPanel} componentParams={{ trendsRSSId }} />
</div>
)
}

View File

@ -25,11 +25,7 @@ const defaultMap = ImmutableMap({
})
const initialState = ImmutableMap({
trends_leadline: ImmutableMap({
title: null,
image: null,
trends_url: null,
}),
trends_leadline: ImmutableMap(),
trends_headlines: defaultMap,
trends_breaking: defaultMap,
gab_news: defaultMap,
@ -72,7 +68,9 @@ const normalizeNewsItem = (item) => {
const setStateKeysOnRequest = (state, keys) => {
return state.withMutations((map) => {
keys.map((key) => map.setIn([key, 'isLoading'], true))
keys.map((key) => {
map.setIn([key, 'isLoading'], true)
})
})
}
@ -107,19 +105,18 @@ export default function (state = initialState, action) {
try {
trendsFetchData.trends_headlines = ImmutableList(action.items.trends.leadHeadlines.map((item) => normalizeHeadlineItem(item)))
trendsFetchData.trends_breaking = ImmutableList(action.items.trends.rssFeedItems.map((item) => normalizeTrendsItem(item)))
trendsFetchData.trends_leadline = ImmutableMap({
title: action.items.trends.headline.title,
image: `https://trends.gab.com/image/${action.items.trends.headline.image._id}`,
trends_url: `https://trends.gab.com/trend?url=${action.items.trends.headline.href}`,
})
} catch (error) {
trendsFetchData = {
breakingItems: ImmutableList(),
headlineItems: ImmutableList(),
trends_leadline: ImmutableMap(),
}
}
// : todo :
// trends_leadline: ImmutableMap({
// title: null,
// image: null,
// trends_url: null,
// }),
return setStateKeysOnSuccess(state, trendsFetchData)
//
@ -148,13 +145,48 @@ export default function (state = initialState, action) {
try {
latestGabNewsData.gab_news = ImmutableList(action.items.map((item) => normalizeNewsItem(item)))
} catch (error) {
console.log("news reducer error: ", error)
latestGabNewsData = {
gab_news: ImmutableList(),
}
}
return setStateKeysOnSuccess(state, latestGabNewsData)
//
case GAB_TREND_FEED_EXPAND_REQUEST:
return state.withMutations((map) => {
const exists = !!map.getIn(['trends_feeds', `${action.feedId}`], null)
if (!exists) {
map.setIn(['trends_feeds', `${action.feedId}`], ImmutableMap({
isLoading: false,
isFetched: false,
items: ImmutableList(),
}))
} else {
map.setIn(['trends_feeds', `${action.feedId}`, 'isLoading'], true)
}
})
case GAB_TREND_FEED_EXPAND_FAIL:
return state.withMutations((map) => {
map.setIn(['trends_feeds', `${action.feedId}`], ImmutableMap({
isLoading: false,
isFetched: true,
items: ImmutableList(),
}))
})
case GAB_TREND_FEED_EXPAND_SUCCESS:
let latestGabTrendFeedData = []
try {
latestGabTrendFeedData = state.getIn(['trends_feeds', `${action.feedId}`, 'items']).concat(action.items.map((item) => normalizeTrendsItem(item)))
} catch (error) {
latestGabTrendFeedData = ImmutableList()
}
return state.withMutations((map) => {
map.setIn(['trends_feeds', `${action.feedId}`, 'isLoading'], false)
map.setIn(['trends_feeds', `${action.feedId}`, 'isFetched'], true)
map.setIn(['trends_feeds', `${action.feedId}`, 'curPage'], action.curPage)
map.setIn(['trends_feeds', `${action.feedId}`, 'items'], latestGabTrendFeedData)
})
default:
return state
}