Added trending_hashtags to redux to fetch on isXS in SearchLayout

• Added:
- trending_hashtags to redux to fetch on isXS in SearchLayout

• Removed:
- trending_hashtags from initial state
This commit is contained in:
mgabdev 2021-01-15 15:36:14 -05:00
parent f7b061845e
commit 2cd09a8e72
5 changed files with 134 additions and 29 deletions

View File

@ -0,0 +1,38 @@
import api from '../api'
import { me } from '../initial_state'
export const TRENDING_HASHTAGS_FETCH_REQUEST = 'TRENDING_HASHTAGS_FETCH_REQUEST'
export const TRENDING_HASHTAGS_FETCH_SUCCESS = 'TRENDING_HASHTAGS_FETCH_SUCCESS'
export const TRENDING_HASHTAGS_FETCH_FAIL = 'TRENDING_HASHTAGS_FETCH_FAIL'
/**
* Fetch trending hashtags
*/
export const fetchTrendingHashtags = () => (dispatch, getState) => {
if (!me) return
const isFetched = getState().getIn(['trending_hashtags', 'fetched'], false)
if (isFetched) return
dispatch(fetchTrendingHashtagsRequest())
api(getState).get('/api/v1/trending_hashtags').then((response) => {
dispatch(fetchTrendingHashtagsSuccess(response.data.trending_hashtags))
}).catch((error) => {
dispatch(fetchTrendingHashtagsFail(error))
})
}
const fetchTrendingHashtagsRequest = () => ({
type: TRENDING_HASHTAGS_FETCH_REQUEST,
})
const fetchTrendingHashtagsSuccess = (hashtags) => ({
type: TRENDING_HASHTAGS_FETCH_SUCCESS,
hashtags,
})
const fetchTrendingHashtagsFail = (error, listType) => ({
type: TRENDING_HASHTAGS_FETCH_FAIL,
error,
})

View File

@ -19,7 +19,6 @@ export const version = getMeta('version');
export const isStaff = getMeta('is_staff'); export const isStaff = getMeta('is_staff');
export const unreadCount = getMeta('unread_count'); export const unreadCount = getMeta('unread_count');
export const lastReadNotificationId = getMeta('last_read_notification_id'); export const lastReadNotificationId = getMeta('last_read_notification_id');
export const trendingHashtags = getMeta('trending_hashtags');
export const isFirstSession = getMeta('is_first_session'); export const isFirstSession = getMeta('is_first_session');
export const emailConfirmed = getMeta('email_confirmed'); export const emailConfirmed = getMeta('email_confirmed');
export const meEmail = getMeta('email'); export const meEmail = getMeta('email');

View File

@ -2,11 +2,12 @@ import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import { defineMessages, injectIntl } from 'react-intl' import { defineMessages, injectIntl } from 'react-intl'
import { me, trendingHashtags } from '../initial_state' import { me } from '../initial_state'
import { import {
BREAKPOINT_EXTRA_SMALL, BREAKPOINT_EXTRA_SMALL,
CX, CX,
} from '../constants' } from '../constants'
import { fetchTrendingHashtags } from '../actions/trending_hashtags'
import Layout from '../layouts/layout' import Layout from '../layouts/layout'
import PageTitle from '../features/ui/util/page_title' import PageTitle from '../features/ui/util/page_title'
import DefaultNavigationBar from '../components/navigation_bar/default_navigation_bar' import DefaultNavigationBar from '../components/navigation_bar/default_navigation_bar'
@ -32,30 +33,18 @@ class SearchLayout extends React.PureComponent {
state = { state = {
isSearchFocused: false, isSearchFocused: false,
currentExploreTabIndex: 0, currentExploreTabIndex: 0,
} setTrendingHashtags: false,
exploreTabs: [
componentWillMount() {
const { intl } = this.props
this.exploreTabs = [
{ {
title: 'Explore', title: 'Explore',
onClick: () => this.setState({ currentExploreTabIndex: 0 }), onClick: () => this.setState({ currentExploreTabIndex: 0 }),
component: ExploreTimeline, component: ExploreTimeline,
} }
] ]
}
if (Array.isArray(trendingHashtags)) { componentWillMount() {
trendingHashtags.forEach((tag, i) => { const { intl } = this.props
let j = i + 1
this.exploreTabs.push({
title: `#${tag}`,
onClick: () => this.setState({ currentExploreTabIndex: j }),
component: HashtagTimeline,
componentParams: { params: { id: `${tag}`.toLowerCase() } },
})
})
}
this.searchTabs = [ this.searchTabs = [
{ {
@ -82,6 +71,48 @@ class SearchLayout extends React.PureComponent {
] ]
} }
componentDidMount() {
this._shouldSetTrendingHashtags()
}
componentDidUpdate(prevProps) {
if (prevProps.trendingHashtags !== this.props.trendingHashtags) {
this._shouldSetTrendingHashtags()
}
}
_shouldSetTrendingHashtags = () => {
const {
isXS,
trendingHashtags,
trendingHashtagsFetched,
} = this.props
const { exploreTabs, setTrendingHashtags } = this.state
if (!isXS || setTrendingHashtags) return false
if (!trendingHashtagsFetched) {
this.props.onFetchTrendingHashtags()
return
}
if (Array.isArray(trendingHashtags) && trendingHashtagsFetched) {
trendingHashtags.forEach((tag, i) => {
let j = i + 1
exploreTabs.push({
title: `#${tag}`,
onClick: () => this.setState({ currentExploreTabIndex: j }),
component: HashtagTimeline,
componentParams: { params: { id: `${tag}`.toLowerCase() } },
})
})
this.setState({
exploreTabs,
setTrendingHashtags: true,
})
}
}
handleOnToggleSearchExplore = (isSearchFocused) => { handleOnToggleSearchExplore = (isSearchFocused) => {
this.setState({ isSearchFocused }) this.setState({ isSearchFocused })
} }
@ -93,15 +124,15 @@ class SearchLayout extends React.PureComponent {
value, value,
} = this.props } = this.props
const { const {
exploreTabs,
isSearchFocused, isSearchFocused,
currentExploreTabIndex, currentExploreTabIndex,
} = this.state } = this.state
const activeExploreTab = exploreTabs[currentExploreTabIndex];
const activeExploreTab = this.exploreTabs[currentExploreTabIndex];
const activeTabComponent = activeExploreTab.component const activeTabComponent = activeExploreTab.component
const activeTabComponentParams = activeExploreTab.componentParams || {} const activeTabComponentParams = activeExploreTab.componentParams || {}
const activeExploreTabs = this.exploreTabs.map((tab, i) => { const activeExploreTabs = exploreTabs.map((tab, i) => {
return { return {
...tab, ...tab,
active: i === currentExploreTabIndex, active: i === currentExploreTabIndex,
@ -184,11 +215,6 @@ class SearchLayout extends React.PureComponent {
} }
SearchLayout.propTypes = {
intl: PropTypes.object.isRequired,
children: PropTypes.node.isRequired,
value: PropTypes.string,
}
const messages = defineMessages({ const messages = defineMessages({
search: { id: 'search', defaultMessage: 'Search' }, search: { id: 'search', defaultMessage: 'Search' },
@ -202,6 +228,24 @@ const messages = defineMessages({
const mapStateToProps = (state) => ({ const mapStateToProps = (state) => ({
value: state.getIn(['search', 'value']), value: state.getIn(['search', 'value']),
trendingHashtags: state.getIn(['trending_hashtags', 'items']),
trendingHashtagsFetched: state.getIn(['trending_hashtags', 'fetched'], false),
isXS: state.getIn(['settings', 'window_dimensions', 'width']) <= BREAKPOINT_EXTRA_SMALL,
}) })
export default injectIntl(connect(mapStateToProps)(SearchLayout)) const mapDispatchToProps = (dispatch) => ({
onFetchTrendingHashtags() {
dispatch(fetchTrendingHashtags())
},
})
SearchLayout.propTypes = {
intl: PropTypes.object.isRequired,
children: PropTypes.node.isRequired,
value: PropTypes.string,
trendingHashtags: PropTypes.array,
isXS: PropTypes.bool.isRequired,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(SearchLayout))

View File

@ -52,6 +52,7 @@ import suggestions from './suggestions'
import timelines from './timelines' import timelines from './timelines'
import timeline_injections from './timeline_injections' import timeline_injections from './timeline_injections'
import toasts from './toasts' import toasts from './toasts'
import trending_hashtags from './trending_hashtags'
import user from './user' import user from './user'
import user_lists from './user_lists' import user_lists from './user_lists'
@ -109,6 +110,7 @@ const reducers = {
timelines, timelines,
timeline_injections, timeline_injections,
toasts, toasts,
trending_hashtags,
user, user,
user_lists, user_lists,
} }

View File

@ -0,0 +1,22 @@
import { Map as ImmutableMap } from 'immutable'
import {
TRENDING_HASHTAGS_FETCH_REQUEST,
TRENDING_HASHTAGS_FETCH_SUCCESS,
TRENDING_HASHTAGS_FETCH_FAIL,
} from '../actions/trending_hashtags'
const initialState = ImmutableMap({
fetched: false,
items: []
})
export default function trending_hashtags(state = initialState, action) {
switch (action.type) {
case TRENDING_HASHTAGS_FETCH_FAIL:
return state.set('fetched', true).set('items', [])
case TRENDING_HASHTAGS_FETCH_SUCCESS:
return state.set('fetched', true).set('items', action.hashtags)
default:
return state
}
}