Finished updating the reformatting of propTypes and set redux, intl functions to end of component

• Finished:
- updating the reformatting of propTypes and set redux, intl functions to end of component

• Removed:
- Gif implementation
This commit is contained in:
mgabdev 2020-08-18 19:22:15 -05:00
parent e21a6ff897
commit 99982c0391
102 changed files with 2540 additions and 3285 deletions

View File

@ -1,110 +0,0 @@
import api from '../api';
import { me } from '../initial_state'
export const GIFS_CLEAR_RESULTS = 'GIFS_CLEAR_RESULTS'
export const GIF_SET_SELECTED = 'GIF_SET_SELECTED'
export const GIF_CHANGE_SEARCH_TEXT = 'GIF_CHANGE_SEARCH_TEXT'
export const GIF_CLEAR_SELECTED = 'GIF_CLEAR_SELECTED'
export const GIF_RESULTS_FETCH_REQUEST = 'GIF_RESULTS_FETCH_REQUEST'
export const GIF_RESULTS_FETCH_SUCCESS = 'GIF_RESULTS_FETCH_SUCCESS'
export const GIF_RESULTS_FETCH_FAIL = 'GIF_RESULTS_FETCH_FAIL'
export const GIF_CATEGORIES_FETCH_REQUEST = 'GIF_CATEGORIES_FETCH_REQUEST'
export const GIF_CATEGORIES_FETCH_SUCCESS = 'GIF_CATEGORIES_FETCH_SUCCESS'
export const GIF_CATEGORIES_FETCH_FAIL = 'GIF_CATEGORIES_FETCH_FAIL'
// : todo :
export const fetchGifCategories = () => {
return function (dispatch, getState) {
if (!me) return
dispatch(fetchGifCategoriesRequest())
api(getState).get('/api/v1/gifs/categories').then(response => {
dispatch(fetchGifCategoriesSuccess(response.data.tags))
}).catch(function (error) {
dispatch(fetchGifCategoriesFail(error))
})
}
}
export const fetchGifResults = (expand) => {
return function (dispatch, getState) {
if (!me) return
dispatch(fetchGifResultsRequest())
const search = getState().getIn(['tenor', 'searchText'], '');
const pos = 0 //expand ? getState().getIn(['tenor', 'results'], []).length
api(getState).get('/api/v1/gifs/search', { search, pos }).then((response) => {
dispatch(fetchGifResultsSuccess(response.data))
}).catch(function (error) {
dispatch(fetchGifResultsFail(error))
})
}
}
export const clearGifResults = () => ({
type: GIFS_CLEAR_RESULTS,
})
export const clearSelectedGif = () => ({
type: GIF_CLEAR_SELECTED,
result,
})
export const setSelectedGif = (result) => ({
type: GIF_SET_SELECTED,
result,
})
export function changeGifSearchText(text) {
return {
type: GIF_CHANGE_SEARCH_TEXT,
text,
}
}
function fetchGifResultsRequest() {
return {
type: GIF_RESULTS_FETCH_REQUEST,
}
}
function fetchGifResultsSuccess(data) {
return {
type: GIF_RESULTS_FETCH_SUCCESS,
data,
}
}
function fetchGifResultsFail(error) {
return {
type: GIF_RESULTS_FETCH_FAIL,
error,
}
}
function fetchGifCategoriesRequest() {
return {
type: GIF_CATEGORIES_FETCH_REQUEST,
}
}
function fetchGifCategoriesSuccess(categories) {
return {
type: GIF_CATEGORIES_FETCH_SUCCESS,
categories,
}
}
function fetchGifCategoriesFail(error) {
return {
type: GIF_CATEGORIES_FETCH_FAIL,
error,
}
}

View File

@ -1,25 +1,9 @@
import React from 'react'
import PropTypes from 'prop-types'
/**
* Renders a block component
*/
class Block extends React.PureComponent {
render() {
const { children } = this.props
return (
<div className={[_s.d, _s.boxShadowBlock, _s.bgPrimary, _s.overflowHidden, _s.radiusSmall].join(' ')}>
{children}
</div>
)
}
}
Block.propTypes = {
children: PropTypes.any,
}
const Block = ({ children }) => (
<div className={[_s.d, _s.boxShadowBlock, _s.bgPrimary, _s.overflowHidden, _s.radiusSmall].join(' ')}>
{children}
</div>
)
export default Block

View File

@ -165,11 +165,6 @@ class Comment extends ImmutablePureComponent {
class CommentButton extends React.PureComponent {
static propTypes = {
onClick: PropTypes.func.isRequired,
title: PropTypes.string.isRequired,
}
render() {
const { onClick, title } = this.props
@ -191,6 +186,11 @@ class CommentButton extends React.PureComponent {
}
CommentButton.propTypes = {
onClick: PropTypes.func.isRequired,
title: PropTypes.string.isRequired,
}
const messages = defineMessages({
reply: { id: 'status.reply', defaultMessage: 'Reply' },
like: { id: 'status.like', defaultMessage: 'Like' },

View File

@ -1,13 +1,8 @@
import React from 'react'
import PropTypes from 'prop-types'
import Text from './text'
export default class DotTextSeperator extends React.PureComponent {
const DotTextSeperator = () => (
<Text size='small' color='secondary' className={_s.ml5}>·</Text>
)
render() {
return (
<Text size='small' color='secondary' className={_s.ml5}>·</Text>
)
}
}
export default DotTextSeperator

View File

@ -1,5 +1,4 @@
import React from 'react'
import PropTypes from 'prop-types'
export default class Dummy extends React.PureComponent {

View File

@ -6,178 +6,157 @@ import Icon from './icon'
import Text from './text'
import ResponsiveClassesComponent from '../features/ui/util/responsive_classes_component'
export default class GlobalFooter extends React.PureComponent {
const GlobalFooter = () => (
<div className={[_s.d, _s.z4, _s.w100PC].join(' ')}>
<div className={[_s.d, _s.left0, _s.right0, _s.bottom0, _s.w100PC, _s.bgSubtle, _s.borderTop1PX, _s.aiCenter, _s.borderColorSecondary].join(' ')}>
render() {
<div className={[_s.d, _s.mt15, _s.mb15].join(' ')}>
<ResponsiveClassesComponent
classNames={[_s.d, _s.w1255PX, _s.flexRow, _s.py15, _s.mt15, _s.mb15].join(' ')}
classNamesSmall={[_s.d, _s.w1255PX, _s.aiCenter, _s.pt15, _s.px15, _s.mt15].join(' ')}
>
return (
<div className={[_s.d, _s.z4, _s.w100PC].join(' ')}>
<div className={[_s.d, _s.left0, _s.right0, _s.bottom0, _s.w100PC, _s.bgSubtle, _s.borderTop1PX, _s.aiCenter, _s.borderColorSecondary].join(' ')}>
<ResponsiveClassesComponent
classNames={[_s.d, _s.w330PX].join(' ')}
classNamesSmall={[_s.d, _s.aiCenter].join(' ')}
>
<div className={[_s.d, _s.mb10].join(' ')}>
<Icon id='logo' />
</div>
<div className={[_s.d, _s.pr15, _s.maxW640PX].join(' ')}>
<Text size='medium'>We build Freedom Of Speech Software. We champion free speech, individual liberty and the free flow of information online. All are welcome.</Text>
</div>
</ResponsiveClassesComponent>
<div className={[_s.d, _s.mt15, _s.mb15].join(' ')}>
<ResponsiveClassesComponent
classNames={[_s.d, _s.w1255PX, _s.flexRow, _s.py15, _s.mt15, _s.mb15].join(' ')}
classNamesSmall={[_s.d, _s.w1255PX, _s.aiCenter, _s.pt15, _s.px15, _s.mt15].join(' ')}
>
<ResponsiveClassesComponent
classNames={[_s.d, _s.flexRow, _s.flexGrow1, _s.pl15].join(' ')}
classNamesSmall={[_s.d, _s.py15, _s.w100PC, _s.px15].join(' ')}
>
<ResponsiveClassesComponent
classNames={[_s.d, _s.w330PX].join(' ')}
classNamesSmall={[_s.d, _s.aiCenter].join(' ')}
>
<div className={[_s.d, _s.mb10].join(' ')}>
<Icon id='logo' />
</div>
<div className={[_s.d, _s.pr15, _s.maxW640PX].join(' ')}>
<Text size='medium'>We build Freedom Of Speech Software. We champion free speech, individual liberty and the free flow of information online. All are welcome.</Text>
</div>
</ResponsiveClassesComponent>
<GlobalFooterColumn
title='Join'
items={[
{
href: 'https://gab.com',
title: 'Gab Social',
},
{
href: 'https://dissenter.com',
title: 'Dissenter Browser',
},
{
href: 'https://chat.gab.com',
title: 'Gab Chat',
},
]}
/>
<ResponsiveClassesComponent
classNames={[_s.d, _s.flexRow, _s.flexGrow1, _s.pl15].join(' ')}
classNamesSmall={[_s.d, _s.py15, _s.w100PC, _s.px15].join(' ')}
>
<GlobalFooterColumn
title='Stay Informed'
items={[
{
href: 'https://trends.gab.com',
title: 'Gab Trends',
},
{
href: 'https://news.gab.com',
title: 'Gab News',
},
{
href: 'https://apps.gab.com',
title: 'Gab Apps',
},
]}
/>
<GlobalFooterColumn
title='Join'
items={[
{
href: 'https://gab.com',
title: 'Gab Social',
},
{
href: 'https://dissenter.com',
title: 'Dissenter Browser',
},
{
href: 'https://chat.gab.com',
title: 'Gab Chat',
},
]}
/>
<GlobalFooterColumn
title='Support Us'
items={[
{
href: 'https://pro.gab.com',
title: 'Go PRO',
},
{
href: 'https://shop.dissenter.com',
title: 'Merch Store',
},
{
href: 'https://news.gab.com/support-gab',
title: 'Affiliates',
},
]}
/>
<GlobalFooterColumn
title='Stay Informed'
items={[
{
href: 'https://trends.gab.com',
title: 'Gab Trends',
},
{
href: 'https://news.gab.com',
title: 'Gab News',
},
{
href: 'https://apps.gab.com',
title: 'Gab Apps',
},
]}
/>
<GlobalFooterColumn
title='Legal'
items={[
{
to: '/about/tos',
title: 'Terms of Service',
},
{
to: '/about/privacy',
title: 'Privacy Policy',
},
{
to: '/about/dmca',
title: 'Copyright Policy',
},
{
href: 'https://help.gab.com',
title: 'Contact Us',
},
]}
/>
<GlobalFooterColumn
title='Support Us'
items={[
{
href: 'https://pro.gab.com',
title: 'Go PRO',
},
{
href: 'https://shop.dissenter.com',
title: 'Merch Store',
},
{
href: 'https://news.gab.com/support-gab',
title: 'Affiliates',
},
]}
/>
<GlobalFooterColumn
title='Legal'
items={[
{
to: '/about/tos',
title: 'Terms of Service',
},
{
to: '/about/privacy',
title: 'Privacy Policy',
},
{
to: '/about/dmca',
title: 'Copyright Policy',
},
{
href: 'https://help.gab.com',
title: 'Contact Us',
},
]}
/>
</ResponsiveClassesComponent>
</ResponsiveClassesComponent>
</div>
<div className={[_s.d, _s.aiCenter, _s.bgSecondary, _s.h100PC, _s.minH58PX, _s.w100PC, _s.saveAreaInsetPB, _s.jcSpaceAround].join(' ')}>
<ResponsiveClassesComponent
classNames={[_s.d, _s.w1255PX, _s.flexRow, _s.aiCenter].join(' ')}
classNamesXS={[_s.d, _s.w1255PX, _s.aiCenter, _s.px15, _s.pt15].join(' ')}
>
<div classNames={[_s.d, _s.flexRow, _s.aiCenter].join(' ')}>
<Text weight='bold'>
© 2020
</Text>
<Text>
&nbsp;Copyright |&nbsp;
</Text>
<Button
isText
color='primary'
backgroundColor='none'
className={_s.displayInline}
href='https://gab.com'
>
<Text>Gab AI Inc.</Text>
</Button>
</div>
<ResponsiveClassesComponent
classNames={[_s.d, _s.aiCenter, _s.mlAuto].join(' ')}
classNamesXS={[_s.d, _s.aiCenter, _s.py15].join(' ')}
>
<Text>
Made in USA 🇺🇸
</Text>
</ResponsiveClassesComponent>
</ResponsiveClassesComponent>
</div>
</div>
</ResponsiveClassesComponent>
</ResponsiveClassesComponent>
</div>
)
}
}
<div className={[_s.d, _s.aiCenter, _s.bgSecondary, _s.h100PC, _s.minH58PX, _s.w100PC, _s.saveAreaInsetPB, _s.jcSpaceAround].join(' ')}>
<ResponsiveClassesComponent
classNames={[_s.d, _s.w1255PX, _s.flexRow, _s.aiCenter].join(' ')}
classNamesXS={[_s.d, _s.w1255PX, _s.aiCenter, _s.px15, _s.pt15].join(' ')}
>
<div classNames={[_s.d, _s.flexRow, _s.aiCenter].join(' ')}>
<Text weight='bold'>
© 2020
</Text>
<Text>
&nbsp;Copyright |&nbsp;
</Text>
<Button
isText
color='primary'
backgroundColor='none'
className={_s.displayInline}
href='https://gab.com'
>
<Text>Gab AI Inc.</Text>
</Button>
</div>
<ResponsiveClassesComponent
classNames={[_s.d, _s.aiCenter, _s.mlAuto].join(' ')}
classNamesXS={[_s.d, _s.aiCenter, _s.py15].join(' ')}
>
<Text>
Made in USA 🇺🇸
</Text>
</ResponsiveClassesComponent>
</ResponsiveClassesComponent>
</div>
</div>
</div>
)
class GlobalFooterColumn extends React.PureComponent {
static propTypes = {
title: PropTypes.string,
items: PropTypes.array,
}
componentWillMount() {
this.buttonOptions = {
backgroundColor: 'none',
color: 'primary',
isText: true,
}
}
render() {
const { title, items } = this.props
const { buttonOptions } = this
return (
<ResponsiveClassesComponent
@ -189,7 +168,7 @@ class GlobalFooterColumn extends React.PureComponent {
</div>
{
items.map((item, i) => (
<Button {...buttonOptions} to={item.to} href={item.href} key={`global-footer-column-${title}-${i}`}>
<Button backgroundColor='none' color='primary' isText to={item.to} href={item.href} key={`global-footer-column-${title}-${i}`}>
<Text color='secondary' className={[_s.lineHeight15, _s.pt2].join(' ')}>{item.title}</Text>
</Button>
))
@ -199,4 +178,11 @@ class GlobalFooterColumn extends React.PureComponent {
}
}
}
GlobalFooterColumn.propTypes = {
title: PropTypes.string,
items: PropTypes.array,
}
export default GlobalFooter

View File

@ -166,14 +166,6 @@ class DisplayOptionsModal extends ImmutablePureComponent {
class ThemeBlock extends React.PureComponent {
static propTypes = {
checked: PropTypes.bool,
onChange: PropTypes.func.isRequired,
title: PropTypes.string,
value: PropTypes.string,
style: PropTypes.object,
}
render() {
const {
checked,
@ -215,6 +207,14 @@ class ThemeBlock extends React.PureComponent {
}
ThemeBlock.propTypes = {
checked: PropTypes.bool,
onChange: PropTypes.func.isRequired,
title: PropTypes.string,
value: PropTypes.string,
style: PropTypes.object,
}
const messages = defineMessages({
message: { id: 'display_options.message', defaultMessage: 'Display settings affect your Gab account on this browser. These settings are only visible to you.' },
title: { id: 'display_options', defaultMessage: 'Customize your view' },

View File

@ -1,279 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { defineMessages, injectIntl } from 'react-intl'
import {
fetchGifCategories,
fetchGifResults,
clearGifResults,
setSelectedGif,
changeGifSearchText
} from '../../actions/tenor'
import Block from '../block'
import Button from '../button'
import ColumnIndicator from '../column_indicator'
import Image from '../image'
import Input from '../input'
import Text from '../text'
class GifPickerModal extends React.PureComponent {
state = {
row: 0,
}
componentDidMount() {
this.props.handleFetchCategories()
}
onChange = (value) => {
this.props.handleOnChange(value)
}
onHandleCloseModal = () => {
this.props.handleCloseModal()
}
handleSelectCategory = (category) => {
this.props.handleOnChange(category)
}
handleSelectGifResult = (resultBlock) => {
this.props.handleSelectResult(resultBlock)
}
render() {
const {
intl,
categories,
results,
loading,
error,
searchText,
} = this.props
return (
<div style={{ width: '560px' }}>
<Block>
<div className={[_s.d, _s.flexRow, _s.aiCenter, _s.jcCenter, _s.borderBottom1PX, _s.borderColorSecondary, _s.h53PX, _s.px15].join(' ')}>
<div className={[_s.d, _s.flexGrow1, _s.mr5].join(' ')}>
<Input
onChange={this.onChange}
value={searchText}
prependIcon='search'
placeholder={intl.formatMessage(messages.searchGifs)}
/>
</div>
<Button
backgroundColor='none'
title={intl.formatMessage(messages.close)}
className={_s.mlAuto}
onClick={this.onHandleCloseModal}
color='secondary'
icon='close'
iconSize='10px'
/>
</div>
<div className={[_s.d, _s.minH50VH, _s.maxH80VH, _s.overflowYScroll].join(' ')}>
{
error &&
<ColumnIndicator type='error' />
}
{
(loading && results.length === 0 && categories.length === 0) &&
<ColumnIndicator type='loading' />
}
{
(results.length > 0 || categories.length > 0) &&
<div className={[_s.d, _s.w100PC, _s.h100PC].join(' ')}>
{
results.length === 0 && categories.length > 0 &&
<GifCategoriesCollection categories={categories} handleSelectCategory={this.handleSelectCategory} />
}
{
results.length > 0 &&
<GifResultsCollection results={results} handleSelectGifResult={this.handleSelectGifResult} />
}
</div>
}
</div>
</Block>
</div>
)
}
}
class GifResultsCollectionColumn extends React.PureComponent {
static propTypes = {
results: PropTypes.array.isRequired,
handleSelectGifResult: PropTypes.func.isRequired,
}
onClick = (resultId) => {
this.props.handleSelectGifResult(resultId)
}
render() {
const { results } = this.props
return (
<div className={[_s.d, _s.flexNormal].join(' ')}>
{
results.map((result, i) => (
<button
key={`gif-result-item-${i}`}
onClick={() => this.onClick(result)}
className={[_s.d, _s.outlineNone, _s.bgTransparent, _s.cursorPointer, _s.px2, _s.py2].join(' ')}
>
<Image
height={result.media[0].tinygif.dims[1]}
src={result.media[0].tinygif.url}
/>
</button>
))
}
</div>
)
}
}
class GifResultsCollection extends React.PureComponent {
static propTypes = {
results: PropTypes.array.isRequired,
handleSelectGifResult: PropTypes.func.isRequired,
}
render() {
const { results, handleSelectGifResult } = this.props
// : todo :
const count = results.length
const columnIndex = 10
return (
<div className={[_s.d, _s.h100PC, _s.flexRow, _s.w100PC].join(' ')}>
<GifResultsCollectionColumn
results={results.slice(0, columnIndex)}
handleSelectGifResult={handleSelectGifResult}
/>
<GifResultsCollectionColumn
results={results.slice(columnIndex, columnIndex * 2)}
handleSelectGifResult={handleSelectGifResult}
/>
<GifResultsCollectionColumn
results={results.slice(columnIndex * 2, count)}
handleSelectGifResult={handleSelectGifResult}
/>
</div>
)
}
}
class GifCategoriesCollection extends React.PureComponent {
static propTypes = {
categories: PropTypes.array.isRequired,
handleSelectCategory: PropTypes.func.isRequired,
}
onClick = (term) => {
this.props.handleSelectCategory(term)
}
render() {
const { categories } = this.props
return (
<div className={[_s.d, _s.h100PC, _s.w100PC, _s.flexRow, _s.flexWrap].join(' ')}>
{
categories.map((category, i) => (
<button
key={`gif-category-${i}`}
onClick={() => this.onClick(category.searchterm)}
className={[_s.d, _s.outlineNone, _s.bgTransparent, _s.px2, _s.py2, _s.w50PC].join(' ')}
>
<div className={[_s.d, _s.cursorPointer].join(' ')}>
<Image
height={150}
src={category.image}
/>
<div className={[_s.d, _s.posAbs, _s.videoPlayerControlsBackground, _s.right0, _s.bottom0, _s.left0, _s.py10, _s.px10].join(' ')}>
<Text color='white' weight='bold' size='extraLarge'>
{category.searchterm}
</Text>
</div>
</div>
</button>
))
}
</div>
)
}
}
const messages = defineMessages({
close: { id: 'lightbox.close', defaultMessage: 'Close' },
title: { id: 'pick_gif', defaultMessage: 'Select a GIF' },
searchGifs: { id: 'search_gifs', defaultMessage: 'Search for GIFs' },
})
const mapStateToProps = (state) => ({
categories: state.getIn(['tenor', 'categories']),
suggestions: state.getIn(['tenor', 'suggestions']),
results: state.getIn(['tenor', 'results']),
loading: state.getIn(['tenor', 'loading']),
error: state.getIn(['tenor', 'error']),
searchText: state.getIn(['tenor', 'searchText']),
})
const mapDispatchToProps = (dispatch, { onClose }) => ({
handleCloseModal() {
dispatch(changeGifSearchText(''))
dispatch(clearGifResults())
onClose()
},
handleFetchCategories: () => {
dispatch(fetchGifCategories())
},
handleOnChange: (value) => {
dispatch(changeGifSearchText(value))
if (value.length >= 3) {
dispatch(fetchGifResults())
} else if (value.length === 0) {
dispatch(clearGifResults())
}
},
handleSelectResult: (result) => {
dispatch(setSelectedGif(result))
onClose()
},
// dispatchSubmit: (e) => {
// e.preventDefault();
// dispatch(getGifs());
// },
})
GifPickerModal.propTypes = {
intl: PropTypes.object.isRequired,
handleCloseModal: PropTypes.func.isRequired,
handleFetchCategories: PropTypes.func.isRequired,
handleOnChange: PropTypes.func.isRequired,
handleSelectResult: PropTypes.func.isRequired,
categories: PropTypes.array.isRequired,
results: PropTypes.array.isRequired,
loading: PropTypes.bool,
error: PropTypes.bool,
searchText: PropTypes.string,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(GifPickerModal))

View File

@ -1,60 +1,20 @@
import React from 'react'
import PropTypes from 'prop-types'
import { defineMessages, injectIntl } from 'react-intl'
import ImmutablePureComponent from 'react-immutable-pure-component'
import Button from '../button'
import Text from '../text'
import ModalLayout from './modal_layout'
class HomeTimelineSettingsModal extends ImmutablePureComponent {
class GroupTimelineSettingsModal extends React.PureComponent {
render() {
const { intl } = this.props
return (
<div>
<Text>
{intl.formatMessage(messages.text)}
</Text>
<Text>
{intl.formatMessage(messages.benefits)}
</Text>
<div className={[_s.d, _s.my10].join(' ')}>
<Text> Schedule Posts</Text>
<Text> Get Verified</Text>
<Text> Create Groups</Text>
<Text> Larger Video and Image Uploads</Text>
<Text> Receive the PRO Badge</Text>
<Text> Remove in-feed promotions</Text>
</div>
<Button
backgroundColor='brand'
color='white'
icon='pro'
href='https://pro.gab.com'
className={_s.jcCenter}
iconClassName={[_s.mr5, _s.cWhite].join(' ')}
>
<Text color='inherit' weight='bold' align='center'>
{intl.formatMessage(messages.title)}
</Text>
</Button>
</div>
<div/>
)
}
}
const messages = defineMessages({
title: { id: 'promo.gab_pro', defaultMessage: 'Upgrade to GabPRO' },
text: { id: 'pro_upgrade_modal.text', defaultMessage: 'Gab is fully funded by people like you. Please consider supporting us on our mission to defend free expression online for all people.' },
benefits: { id: 'pro_upgrade_modal.benefits', defaultMessage: 'Here are just some of the benefits that thousands of GabPRO members receive:' },
})
HomeTimelineSettingsModal.propTypes = {
GroupTimelineSettingsModal.propTypes = {
intl: PropTypes.object.isRequired,
}
export default injectIntl(HomeTimelineSettingsModal)
export default injectIntl(GroupTimelineSettingsModal)

View File

@ -1,12 +1,11 @@
import React from 'react'
import PropTypes from 'prop-types'
import { defineMessages, injectIntl } from 'react-intl'
import ImmutablePureComponent from 'react-immutable-pure-component'
import ModalLayout from './modal_layout'
import Text from '../text'
import Heading from '../heading'
class HotkeysModal extends ImmutablePureComponent {
class HotkeysModal extends React.PureComponent {
render() {
const { intl, onClose } = this.props
@ -89,29 +88,22 @@ class HotkeysModal extends ImmutablePureComponent {
}
class HotKeysModalRow extends React.PureComponent {
render() {
const { hotkey, action } = this.props
return (
<tr>
<td>
<kbd>
<Text size='small'>
{hotkey}
</Text>
</kbd>
</td>
<td>
<Text size='small'>
{action}
</Text>
</td>
</tr>
)
}
}
const HotKeysModalRow = ({ hotkey, action }) => (
<tr>
<td>
<kbd>
<Text size='small'>
{hotkey}
</Text>
</kbd>
</td>
<td>
<Text size='small'>
{action}
</Text>
</td>
</tr>
)
HotKeysModalRow.propTypes = {
hotkey: PropTypes.string.isRequired,

View File

@ -1,11 +1,10 @@
import React from 'react'
import PropTypes from 'prop-types'
import { defineMessages, injectIntl } from 'react-intl'
import ImmutablePureComponent from 'react-immutable-pure-component'
import ModalLayout from './modal_layout'
import ListCreate from '../../features/list_create'
class ListCreateModal extends ImmutablePureComponent {
class ListCreateModal extends React.PureComponent {
render() {
const { intl, onClose } = this.props

View File

@ -1,12 +1,11 @@
import React from 'react'
import PropTypes from 'prop-types'
import { defineMessages, injectIntl } from 'react-intl'
import ImmutablePureComponent from 'react-immutable-pure-component'
import ModalLayout from './modal_layout'
import { ListEdit } from '../../features/ui/util/async_components'
import WrappedBundle from '../../features/ui/util/wrapped_bundle'
class ListEditorModal extends ImmutablePureComponent {
class ListEditorModal extends React.PureComponent {
render() {
const { intl, onClose, id } = this.props

View File

@ -1,7 +1,7 @@
import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { injectIntl, FormattedMessage, defineMessages } from 'react-intl'
import { injectIntl, defineMessages } from 'react-intl'
import { getWindowDimension } from '../../utils/is_mobile'
import { openModal } from '../../actions/modal'
import { cancelReplyCompose } from '../../actions/compose'
@ -9,7 +9,6 @@ import {
CX,
BREAKPOINT_EXTRA_SMALL,
} from '../../constants'
import Responsive from '../../features/ui/util/responsive_component'
const initialState = getWindowDimension()

View File

@ -17,7 +17,6 @@ import {
MODAL_EDIT_PROFILE,
MODAL_EDIT_SHORTCUTS,
MODAL_EMBED,
MODAL_GIF_PICKER,
MODAL_GROUP_CREATE,
MODAL_GROUP_DELETE,
MODAL_HASHTAG_TIMELINE_SETTINGS,
@ -49,7 +48,6 @@ import {
EditProfileModal,
EditShortcutsModal,
EmbedModal,
GifPickerModal,
GroupCreateModal,
GroupDeleteModal,
GroupMembersModal,
@ -84,7 +82,6 @@ MODAL_COMPONENTS[MODAL_DISPLAY_OPTIONS] = DisplayOptionsModal
MODAL_COMPONENTS[MODAL_EDIT_SHORTCUTS] = EditShortcutsModal
MODAL_COMPONENTS[MODAL_EDIT_PROFILE] = EditProfileModal
MODAL_COMPONENTS[MODAL_EMBED] = EmbedModal
MODAL_COMPONENTS[MODAL_GIF_PICKER] = GifPickerModal
MODAL_COMPONENTS[MODAL_GROUP_CREATE] = GroupCreateModal
MODAL_COMPONENTS[MODAL_GROUP_DELETE] = GroupDeleteModal
MODAL_COMPONENTS[MODAL_HASHTAG_TIMELINE_SETTINGS] = HashtagTimelineSettingsModal

View File

@ -41,13 +41,9 @@ const messages = defineMessages({
mute: { id: 'confirmations.mute.confirm', defaultMessage: 'Mute' },
})
const mapStateToProps = (state, { accountId }) => {
const getAccount = makeGetAccount()
return {
account: getAccount(state, accountId),
}
}
const mapStateToProps = (state, { accountId }) => ({
account: makeGetAccount()(state, accountId),
})
const mapDispatchToProps = (dispatch) => ({
onConfirm(account, notifications) {

View File

@ -2,7 +2,6 @@ import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { defineMessages, injectIntl } from 'react-intl'
import ImmutablePureComponent from 'react-immutable-pure-component'
import {
URL_GAB_PRO,
DEFAULT_THEME,
@ -13,7 +12,7 @@ import Icon from '../icon'
import Image from '../image'
import ModalLayout from './modal_layout'
class ProUpgradeModal extends ImmutablePureComponent {
class ProUpgradeModal extends React.PureComponent {
render() {
const {

View File

@ -1,12 +1,11 @@
import React from 'react'
import PropTypes from 'prop-types'
import { defineMessages, injectIntl } from 'react-intl'
import ImmutablePureComponent from 'react-immutable-pure-component'
import ModalLayout from './modal_layout'
import Text from '../text'
import Button from '../button'
class UnauthorizedModal extends ImmutablePureComponent {
class UnauthorizedModal extends React.PureComponent {
render() {
const { intl, onClose } = this.props

View File

@ -15,37 +15,8 @@ import Text from '../text'
import DotTextSeperator from '../dot_text_seperator'
import ProfileInfoPanelPlaceholder from '../placeholder/profile_info_panel_placeholder'
const messages = defineMessages({
title: { id: 'about', defaultMessage: 'About' },
members: { id: 'members', defaultMessage: 'Members' },
created: { id: 'created', defaultMessage: 'Created' },
category: { id: 'category', defaultMessage: 'Category' },
tags: { id: 'tags', defaultMessage: 'Tags' },
privateGroup: { id: 'group.private', defaultMessage: 'Private' },
publicGroup: { id: 'group.public', defaultMessage: 'Public' },
visibleGroup: { id: 'group.visible', defaultMessage: 'Visible' },
invisibleGroup: { id: 'group.invisible', defaultMessage: 'Invisible' },
})
const mapStateToProps = (state, { group }) => {
const groupId = group ? group.get('id') : -1
const relationships = group === -1 ? null : state.getIn(['group_relationships', groupId])
return { relationships }
}
export default
@injectIntl
@connect(mapStateToProps)
class GroupInfoPanel extends ImmutablePureComponent {
static propTypes = {
group: ImmutablePropTypes.map.isRequired,
intl: PropTypes.object.isRequired,
noPanel: PropTypes.bool,
relationships: ImmutablePropTypes.map,
}
render() {
const {
intl,
@ -214,11 +185,6 @@ class GroupInfoPanel extends ImmutablePureComponent {
class GroupInfoPanelRow extends React.PureComponent {
static propTypes = {
icon: PropTypes.string,
title: PropTypes.string.isRequired,
}
render() {
const { icon, title } = this.props
@ -238,4 +204,37 @@ class GroupInfoPanelRow extends React.PureComponent {
}
}
}
GroupInfoPanelRow.propTypes = {
icon: PropTypes.string,
title: PropTypes.string.isRequired,
}
const messages = defineMessages({
title: { id: 'about', defaultMessage: 'About' },
members: { id: 'members', defaultMessage: 'Members' },
created: { id: 'created', defaultMessage: 'Created' },
category: { id: 'category', defaultMessage: 'Category' },
tags: { id: 'tags', defaultMessage: 'Tags' },
privateGroup: { id: 'group.private', defaultMessage: 'Private' },
publicGroup: { id: 'group.public', defaultMessage: 'Public' },
visibleGroup: { id: 'group.visible', defaultMessage: 'Visible' },
invisibleGroup: { id: 'group.invisible', defaultMessage: 'Invisible' },
})
const mapStateToProps = (state, { group }) => {
const groupId = group ? group.get('id') : -1
const relationships = group === -1 ? null : state.getIn(['group_relationships', groupId])
return { relationships }
}
GroupInfoPanel.propTypes = {
group: ImmutablePropTypes.map.isRequired,
intl: PropTypes.object.isRequired,
noPanel: PropTypes.bool,
relationships: ImmutablePropTypes.map,
}
export default injectIntl(connect(mapStateToProps)(GroupInfoPanel))

View File

@ -10,38 +10,8 @@ import GroupListItem from '../group_list_item'
import ScrollableList from '../scrollable_list'
import GroupListItemPlaceholder from '../placeholder/group_list_item_placeholder'
const messages = defineMessages({
memberTitle: { id: 'groups.sidebar-panel.member_title', defaultMessage: 'Groups you\'re in' },
featuredTitle: { id: 'groups.sidebar-panel.featured_title', defaultMessage: 'Featured Groups' },
show_all: { id: 'groups.sidebar-panel.show_all', defaultMessage: 'Show all' },
all: { id: 'groups.sidebar-panel.all', defaultMessage: 'All' },
})
const mapStateToProps = (state, { groupType }) => ({
groupIds: state.getIn(['group_lists', groupType, 'items']),
})
const mapDispatchToProps = (dispatch) => ({
onFetchGroups: (type) => dispatch(fetchGroups(type))
})
export default
@connect(mapStateToProps, mapDispatchToProps)
@injectIntl
class GroupsPanel extends ImmutablePureComponent {
static propTypes = {
groupIds: ImmutablePropTypes.list,
isLazy: PropTypes.bool,
onFetchGroups: PropTypes.func.isRequired,
shouldLoad: PropTypes.bool,
groupType: PropTypes.string,
}
static defaultProps = {
groupType: 'member'
}
state = {
fetched: false,
}
@ -109,4 +79,33 @@ class GroupsPanel extends ImmutablePureComponent {
)
}
}
}
const messages = defineMessages({
memberTitle: { id: 'groups.sidebar-panel.member_title', defaultMessage: 'Groups you\'re in' },
featuredTitle: { id: 'groups.sidebar-panel.featured_title', defaultMessage: 'Featured Groups' },
show_all: { id: 'groups.sidebar-panel.show_all', defaultMessage: 'Show all' },
all: { id: 'groups.sidebar-panel.all', defaultMessage: 'All' },
})
const mapStateToProps = (state, { groupType }) => ({
groupIds: state.getIn(['group_lists', groupType, 'items']),
})
const mapDispatchToProps = (dispatch) => ({
onFetchGroups: (type) => dispatch(fetchGroups(type))
})
GroupsPanel.propTypes = {
groupIds: ImmutablePropTypes.list,
isLazy: PropTypes.bool,
onFetchGroups: PropTypes.func.isRequired,
shouldLoad: PropTypes.bool,
groupType: PropTypes.string,
}
GroupsPanel.defaultProps = {
groupType: 'member'
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(GroupsPanel))

View File

@ -10,21 +10,8 @@ import Divider from '../divider'
import Icon from '../icon'
import Text from '../text'
const messages = defineMessages({
title: { id: 'lists_information', defaultMessage: 'List Information' },
edit: { id: 'edit', defaultMessage: 'Edit' },
})
export default
@injectIntl
class ListDetailsPanel extends ImmutablePureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
list: ImmutablePropTypes.map,
onEdit: PropTypes.func.isRequired,
}
render() {
const {
intl,
@ -77,4 +64,17 @@ class ListDetailsPanel extends ImmutablePureComponent {
</PanelLayout>
)
}
}
}
const messages = defineMessages({
title: { id: 'lists_information', defaultMessage: 'List Information' },
edit: { id: 'edit', defaultMessage: 'Edit' },
})
ListDetailsPanel.propTypes = {
intl: PropTypes.object.isRequired,
list: ImmutablePropTypes.map,
onEdit: PropTypes.func.isRequired,
}
export default injectIntl(ListDetailsPanel)

View File

@ -9,33 +9,8 @@ import { fetchLists } from '../../actions/lists'
import PanelLayout from './panel_layout'
import List from '../list'
const messages = defineMessages({
title: { id: 'lists.subheading', defaultMessage: 'Your Lists' },
show_all: { id: 'groups.sidebar-panel.show_all', defaultMessage: 'Show all' },
all: { id: 'groups.sidebar-panel.all', defaultMessage: 'All' },
})
const mapStateToProps = (state) => ({
lists: getOrderedLists(state),
})
const mapDispatchToProps = (dispatch) => ({
onFetchLists: () => dispatch(fetchLists()),
})
export default
@connect(mapStateToProps, mapDispatchToProps)
@injectIntl
class ListsPanel extends ImmutablePureComponent {
static propTypes = {
onFetchLists: PropTypes.func.isRequired,
lists: ImmutablePropTypes.list,
intl: PropTypes.object.isRequired,
isLazy: PropTypes.bool,
shouldLoad: PropTypes.bool,
}
state = {
fetched: false,
}
@ -96,4 +71,28 @@ class ListsPanel extends ImmutablePureComponent {
)
}
}
}
const messages = defineMessages({
title: { id: 'lists.subheading', defaultMessage: 'Your Lists' },
show_all: { id: 'groups.sidebar-panel.show_all', defaultMessage: 'Show all' },
all: { id: 'groups.sidebar-panel.all', defaultMessage: 'All' },
})
const mapStateToProps = (state) => ({
lists: getOrderedLists(state),
})
const mapDispatchToProps = (dispatch) => ({
onFetchLists: () => dispatch(fetchLists()),
})
ListsPanel.propTypes = {
onFetchLists: PropTypes.func.isRequired,
lists: ImmutablePropTypes.list,
intl: PropTypes.object.isRequired,
isLazy: PropTypes.bool,
shouldLoad: PropTypes.bool,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(ListsPanel))

View File

@ -10,35 +10,8 @@ import PanelLayout from './panel_layout'
import MediaItem from '../media_item'
import MediaGalleryPanelPlaceholder from '../placeholder/media_gallery_panel_placeholder'
const messages = defineMessages({
title: { id: 'media_gallery_panel.title', defaultMessage: 'Media' },
show_all: { id: 'media_gallery_panel.all', defaultMessage: 'Show all' },
})
const mapStateToProps = (state, { account }) => {
const accountId = !!account ? account.get('id') : -1
return {
accountId,
isLoading: state.getIn(['timelines', `account:${accountId}:media`, 'isLoading'], true),
attachments: getAccountGallery(state, accountId),
}
}
export default
@connect(mapStateToProps)
@injectIntl
class MediaGalleryPanel extends ImmutablePureComponent {
static propTypes = {
dispatch: PropTypes.func.isRequired,
accountId: PropTypes.string,
account: ImmutablePropTypes.map,
isLoading: PropTypes.bool,
attachments: ImmutablePropTypes.list.isRequired,
intl: PropTypes.object.isRequired,
}
componentDidMount() {
const { accountId } = this.props
@ -93,3 +66,29 @@ class MediaGalleryPanel extends ImmutablePureComponent {
)
}
}
const messages = defineMessages({
title: { id: 'media_gallery_panel.title', defaultMessage: 'Media' },
show_all: { id: 'media_gallery_panel.all', defaultMessage: 'Show all' },
})
const mapStateToProps = (state, { account }) => {
const accountId = !!account ? account.get('id') : -1
return {
accountId,
isLoading: state.getIn(['timelines', `account:${accountId}:media`, 'isLoading'], true),
attachments: getAccountGallery(state, accountId),
}
}
MediaGalleryPanel.propTypes = {
dispatch: PropTypes.func.isRequired,
accountId: PropTypes.string,
account: ImmutablePropTypes.map,
isLoading: PropTypes.bool,
attachments: ImmutablePropTypes.list.isRequired,
intl: PropTypes.object.isRequired,
}
export default injectIntl(connect(mapStateToProps)(MediaGalleryPanel))

View File

@ -9,35 +9,8 @@ import { setFilter } from '../../actions/notifications'
import PanelLayout from './panel_layout'
import SettingSwitch from '../setting_switch'
const messages = defineMessages({
title: { id: 'notification_filters', defaultMessage: 'Notification Filters' },
onlyVerified: { id: 'notification_only_verified', defaultMessage: 'Only Verified Users' },
// onlyFollowing: { id: 'notification_only_following', defaultMessage: 'Only People I Follow' },
})
const mapStateToProps = (state) => ({
settings: state.getIn(['notifications', 'filter']),
isPro: state.getIn(['accounts', me, 'is_pro']),
})
const mapDispatchToProps = (dispatch) => ({
onChange(path, value) {
dispatch(setFilter(path, value))
},
})
export default
@injectIntl
@connect(mapStateToProps, mapDispatchToProps)
class NotificationFilterPanel extends ImmutablePureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
onChange: PropTypes.func.isRequired,
settings: ImmutablePropTypes.map.isRequired,
isPro: PropTypes.bool.isRequired,
}
render() {
const {
intl,
@ -69,4 +42,30 @@ class NotificationFilterPanel extends ImmutablePureComponent {
</PanelLayout>
)
}
}
}
const messages = defineMessages({
title: { id: 'notification_filters', defaultMessage: 'Notification Filters' },
onlyVerified: { id: 'notification_only_verified', defaultMessage: 'Only Verified Users' },
// onlyFollowing: { id: 'notification_only_following', defaultMessage: 'Only People I Follow' },
})
const mapStateToProps = (state) => ({
settings: state.getIn(['notifications', 'filter']),
isPro: state.getIn(['accounts', me, 'is_pro']),
})
const mapDispatchToProps = (dispatch) => ({
onChange(path, value) {
dispatch(setFilter(path, value))
},
})
NotificationFilterPanel.propTypes = {
intl: PropTypes.object.isRequired,
onChange: PropTypes.func.isRequired,
settings: ImmutablePropTypes.map.isRequired,
isPro: PropTypes.bool.isRequired,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(NotificationFilterPanel))

View File

@ -5,21 +5,7 @@ import Heading from '../heading'
import Button from '../button'
import Text from '../text'
export default class PanelLayout extends React.PureComponent {
static propTypes = {
title: PropTypes.string,
subtitle: PropTypes.string,
children: PropTypes.node,
headerButtonTitle: PropTypes.string,
headerButtonAction: PropTypes.func,
headerButtonTo: PropTypes.string,
footerButtonTitle: PropTypes.string,
footerButtonAction: PropTypes.func,
footerButtonTo: PropTypes.string,
footerButtonHref: PropTypes.string,
noPadding: PropTypes.bool,
}
class PanelLayout extends React.PureComponent {
render() {
const {
@ -106,4 +92,20 @@ export default class PanelLayout extends React.PureComponent {
)
}
}
}
PanelLayout.propTypes = {
title: PropTypes.string,
subtitle: PropTypes.string,
children: PropTypes.node,
headerButtonTitle: PropTypes.string,
headerButtonAction: PropTypes.func,
headerButtonTo: PropTypes.string,
footerButtonTitle: PropTypes.string,
footerButtonAction: PropTypes.func,
footerButtonTo: PropTypes.string,
footerButtonHref: PropTypes.string,
noPadding: PropTypes.bool,
}
export default PanelLayout

View File

@ -7,20 +7,8 @@ import Button from '../button'
import Icon from '../icon'
import Text from '../text'
const messages = defineMessages({
title: { id: 'promo.gab_pro', defaultMessage: 'Upgrade to GabPRO' },
text: { id: 'pro_upgrade_modal.text_sm', defaultMessage: 'Please consider supporting us on our mission to defend free expression online for all people.' },
})
export default
@injectIntl
class ProPanel extends React.PureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
isPro: PropTypes.bool.isRequired,
}
render() {
const { intl, isPro } = this.props
@ -68,4 +56,16 @@ class ProPanel extends React.PureComponent {
)
}
}
}
const messages = defineMessages({
title: { id: 'promo.gab_pro', defaultMessage: 'Upgrade to GabPRO' },
text: { id: 'pro_upgrade_modal.text_sm', defaultMessage: 'Please consider supporting us on our mission to defend free expression online for all people.' },
})
ProPanel.propTypes = {
intl: PropTypes.object.isRequired,
isPro: PropTypes.bool.isRequired,
}
export default injectIntl(ProPanel)

View File

@ -12,24 +12,8 @@ import Text from '../text'
import Dummy from '../dummy'
import ProfileInfoPanelPlaceholder from '../placeholder/profile_info_panel_placeholder'
const messages = defineMessages({
title: { id: 'about', defaultMessage: 'About' },
linkVerifiedOn: { id: 'account.link_verified_on', defaultMessage: 'Ownership of this link was checked on {date}' },
account_locked: { id: 'account.locked_info', defaultMessage: 'This account privacy status is set to locked. The owner manually reviews who can follow them.' },
bot: { id: 'account.badges.bot', defaultMessage: 'Bot' },
memberSince: { id: 'account.member_since', defaultMessage: 'Member since {date}' },
})
export default
@injectIntl
class ProfileInfoPanel extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map,
noPanel: PropTypes.bool,
intl: PropTypes.object.isRequired,
}
render() {
const {
intl,
@ -138,4 +122,20 @@ class ProfileInfoPanel extends ImmutablePureComponent {
</Wrapper>
)
}
}
}
const messages = defineMessages({
title: { id: 'about', defaultMessage: 'About' },
linkVerifiedOn: { id: 'account.link_verified_on', defaultMessage: 'Ownership of this link was checked on {date}' },
account_locked: { id: 'account.locked_info', defaultMessage: 'This account privacy status is set to locked. The owner manually reviews who can follow them.' },
bot: { id: 'account.badges.bot', defaultMessage: 'Bot' },
memberSince: { id: 'account.member_since', defaultMessage: 'Member since {date}' },
})
ProfileInfoPanel.propTypes = {
account: ImmutablePropTypes.map,
noPanel: PropTypes.bool,
intl: PropTypes.object.isRequired,
}
export default injectIntl(ProfileInfoPanel)

View File

@ -11,23 +11,8 @@ import Dummy from '../dummy'
import ProfileStatsPanelPlaceholder from '../placeholder/profile_stats_panel_placeholder'
import ResponsiveClassesComponent from '../../features/ui/util/responsive_classes_component'
const messages = defineMessages({
gabs: { id: 'account.gabs', defaultMessage: 'Gabs' },
followers: { id: 'account.followers', defaultMessage: 'Followers' },
follows: { id: 'account.follows', defaultMessage: 'Following' },
likes: { id: 'likes', defaultMessage: 'Likes' },
})
export default
@injectIntl
class ProfileStatsPanel extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map,
intl: PropTypes.object.isRequired,
noPanel: PropTypes.bool,
}
render() {
const {
intl,
@ -82,3 +67,18 @@ class ProfileStatsPanel extends ImmutablePureComponent {
)
}
}
const messages = defineMessages({
gabs: { id: 'account.gabs', defaultMessage: 'Gabs' },
followers: { id: 'account.followers', defaultMessage: 'Followers' },
follows: { id: 'account.follows', defaultMessage: 'Following' },
likes: { id: 'likes', defaultMessage: 'Likes' },
})
ProfileStatsPanel.propTypes = {
account: ImmutablePropTypes.map,
intl: PropTypes.object.isRequired,
noPanel: PropTypes.bool,
}
export default injectIntl(ProfileStatsPanel)

View File

@ -11,21 +11,8 @@ import ProgressBar from '../progress_bar'
import Button from '../button'
import Text from '../text'
const messages = defineMessages({
progressTitle: { id: 'progress_title', defaultMessage: '{value}% covered this month' },
operationsTitle: { id: 'operations_title', defaultMessage: "Gab's Operational Expenses" },
operationsSubtitle: { id: 'operations_subtitle', defaultMessage: 'We are 100% funded by you' },
donationTitle: { id: 'make_donation', defaultMessage: 'Make a Donation' },
})
export default
@injectIntl
class ProgressPanel extends React.PureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
}
render() {
const { intl } = this.props
@ -63,4 +50,17 @@ class ProgressPanel extends React.PureComponent {
)
}
}
}
const messages = defineMessages({
progressTitle: { id: 'progress_title', defaultMessage: '{value}% covered this month' },
operationsTitle: { id: 'operations_title', defaultMessage: "Gab's Operational Expenses" },
operationsSubtitle: { id: 'operations_subtitle', defaultMessage: 'We are 100% funded by you' },
donationTitle: { id: 'make_donation', defaultMessage: 'Make a Donation' },
})
ProgressPanel.propTypes = {
intl: PropTypes.object.isRequired,
}
export default injectIntl(ProgressPanel)

View File

@ -8,32 +8,8 @@ import { setFilter } from '../../actions/search'
import PanelLayout from './panel_layout'
import SettingSwitch from '../setting_switch'
const messages = defineMessages({
title: { id: 'search_filters', defaultMessage: 'Search Filters' },
onlyVerified: { id: 'notification_only_verified', defaultMessage: 'Only Verified Users' },
})
const mapStateToProps = (state) => ({
settings: state.getIn(['search', 'filter']),
})
const mapDispatchToProps = (dispatch) => ({
onChange(path, value) {
dispatch(setFilter(path, value, true))
},
})
export default
@injectIntl
@connect(mapStateToProps, mapDispatchToProps)
class SearchFilterPanel extends ImmutablePureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
onChange: PropTypes.func.isRequired,
settings: ImmutablePropTypes.map.isRequired,
}
componentWillUnmount () {
//reset
this.props.onChange('onlyVerified', false, false)
@ -58,4 +34,27 @@ class SearchFilterPanel extends ImmutablePureComponent {
</PanelLayout>
)
}
}
}
const messages = defineMessages({
title: { id: 'search_filters', defaultMessage: 'Search Filters' },
onlyVerified: { id: 'notification_only_verified', defaultMessage: 'Only Verified Users' },
})
const mapStateToProps = (state) => ({
settings: state.getIn(['search', 'filter']),
})
const mapDispatchToProps = (dispatch) => ({
onChange(path, value) {
dispatch(setFilter(path, value, true))
},
})
SearchFilterPanel.propTypes = {
intl: PropTypes.object.isRequired,
onChange: PropTypes.func.isRequired,
settings: ImmutablePropTypes.map.isRequired,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(SearchFilterPanel))

View File

@ -7,33 +7,8 @@ import { URL_DISSENTER_SHOP } from '../../constants'
import PanelLayout from './panel_layout'
import ShopItem from '../shop_item'
const messages = defineMessages({
title: { id: 'shop_panel.title', defaultMessage: 'Dissenter Shop' },
shop_now: { id: 'shop_panel.shop_now', defaultMessage: 'Visit the Dissenter Shop' },
})
const mapStateToProps = (state) => ({
items: state.getIn(['shop', 'featured', 'items']),
isError: state.getIn(['shop', 'featured', 'isError']),
})
const mapDispatchToProps = (dispatch) => ({
onFetchFeaturedProducts: () => dispatch(fetchFeaturedProducts()),
})
export default
@connect(mapStateToProps, mapDispatchToProps)
@injectIntl
class ShopPanel extends React.PureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
products: PropTypes.array,
isLazy: PropTypes.bool,
onFetchFeaturedProducts: PropTypes.func.isRequired,
isError: PropTypes.bool.isRequired,
}
state = {
fetched: !this.props.isLazy,
}
@ -74,7 +49,7 @@ class ShopPanel extends React.PureComponent {
footerButtonTitle={intl.formatMessage(messages.shop_now)}
footerButtonHref={URL_DISSENTER_SHOP}
>
<div className={[_s.d, _s.flexRow, _s.flexWrap, _s.pl5, _s.pt5].join(' ')}>
<div className={[_s._, _s.flexRow, _s.flexWrap, _s.pl5, _s.pt5].join(' ')}>
{
items.map((block, i) => (
<ShopItem
@ -90,4 +65,28 @@ class ShopPanel extends React.PureComponent {
</PanelLayout>
)
}
}
}
const messages = defineMessages({
title: { id: 'shop_panel.title', defaultMessage: 'Dissenter Shop' },
shop_now: { id: 'shop_panel.shop_now', defaultMessage: 'Visit the Dissenter Shop' },
})
const mapStateToProps = (state) => ({
items: state.getIn(['shop', 'featured', 'items']),
isError: state.getIn(['shop', 'featured', 'isError']),
})
const mapDispatchToProps = (dispatch) => ({
onFetchFeaturedProducts: () => dispatch(fetchFeaturedProducts()),
})
ShopPanel.propTypes = {
intl: PropTypes.object.isRequired,
products: PropTypes.array,
isLazy: PropTypes.bool,
onFetchFeaturedProducts: PropTypes.func.isRequired,
isError: PropTypes.bool.isRequired,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(ShopPanel))

View File

@ -6,22 +6,8 @@ import { CX } from '../../constants'
import Button from '../button'
import Text from '../text'
const messages = defineMessages({
title: { id: 'signup_panel.welcome_title', defaultMessage: 'Welcome to Gab.com' },
subtitle: { id: 'signup_panel.welcome_subtitle', defaultMessage: 'A social network that champions free speech, individual liberty and the free flow of information online. All are welcome.' },
register: { id: 'account.register', defaultMessage: 'Sign up' },
login: { id: 'account.login', defaultMessage: 'Log in' },
})
export default
@injectIntl
class SignUpLogInPanel extends React.PureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
isXS: PropTypes.bool,
}
render() {
const { intl, isXS } = this.props
@ -88,3 +74,17 @@ class SignUpLogInPanel extends React.PureComponent {
}
}
const messages = defineMessages({
title: { id: 'signup_panel.welcome_title', defaultMessage: 'Welcome to Gab.com' },
subtitle: { id: 'signup_panel.welcome_subtitle', defaultMessage: 'A social network that champions free speech, individual liberty and the free flow of information online. All are welcome.' },
register: { id: 'account.register', defaultMessage: 'Sign up' },
login: { id: 'account.login', defaultMessage: 'Log in' },
})
SignUpLogInPanel.propTypes = {
intl: PropTypes.object.isRequired,
isXS: PropTypes.bool,
}
export default injectIntl(SignUpLogInPanel)

View File

@ -6,21 +6,8 @@ import Button from '../button'
import Text from '../text'
import PanelLayout from './panel_layout'
const messages = defineMessages({
title: { id: 'signup_panel.title', defaultMessage: 'New to Gab?' },
subtitle: { id: 'signup_panel.subtitle', defaultMessage: 'Sign up now to speak freely.' },
register: { id: 'account.register', defaultMessage: 'Sign up' },
login: { id: 'account.login', defaultMessage: 'Log in' },
})
export default
@injectIntl
class SignUpPanel extends React.PureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
}
render() {
if (me) return null
@ -57,3 +44,16 @@ class SignUpPanel extends React.PureComponent {
}
}
const messages = defineMessages({
title: { id: 'signup_panel.title', defaultMessage: 'New to Gab?' },
subtitle: { id: 'signup_panel.subtitle', defaultMessage: 'Sign up now to speak freely.' },
register: { id: 'account.register', defaultMessage: 'Sign up' },
login: { id: 'account.login', defaultMessage: 'Log in' },
})
SignUpPanel.propTypes = {
intl: PropTypes.object.isRequired,
}
export default injectIntl(SignUpPanel)

View File

@ -2,7 +2,6 @@ import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { NavLink } from 'react-router-dom'
import { injectIntl, defineMessages } from 'react-intl'
import ImmutablePropTypes from 'react-immutable-proptypes'
import ImmutablePureComponent from 'react-immutable-pure-component'
import { fetchStatus } from '../../actions/statuses'
@ -19,33 +18,8 @@ import ColumnIndicator from '../column_indicator'
import StatusContent from '../status_content'
import StatusMedia from '../status_media'
const messages = defineMessages({
gabs: { id: 'account.posts', defaultMessage: 'Gabs' },
followers: { id: 'account.followers', defaultMessage: 'Followers' },
follows: { id: 'account.follows', defaultMessage: 'Following' },
edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' },
headerPhoto: { id: 'header_photo', defaultMessage: 'Header photo' },
})
const mapStateToProps = (state, { statusId }) => ({
status: makeGetStatus()(state, { id: statusId }),
})
const mapDispatchToProps = (dispatch) => ({
onFetchStatus: (id) => dispatch(fetchStatus(id)),
})
export default
@connect(mapStateToProps, mapDispatchToProps)
@injectIntl
class StatusPromotionPanel extends ImmutablePureComponent {
static propTypes = {
status: ImmutablePropTypes.map.isRequired,
statusId: PropTypes.string.isRequired,
onFetchStatus: PropTypes.func.isRequired,
}
componentDidMount() {
if (!this.props.status) {
this.props.onFetchStatus(this.props.statusId)
@ -135,4 +109,20 @@ class StatusPromotionPanel extends ImmutablePureComponent {
)
}
}
}
const mapStateToProps = (state, { statusId }) => ({
status: makeGetStatus()(state, { id: statusId }),
})
const mapDispatchToProps = (dispatch) => ({
onFetchStatus: (id) => dispatch(fetchStatus(id)),
})
StatusPromotionPanel.propTypes = {
status: ImmutablePropTypes.map.isRequired,
statusId: PropTypes.string.isRequired,
onFetchStatus: PropTypes.func.isRequired,
}
export default connect(mapStateToProps, mapDispatchToProps)(StatusPromotionPanel)

View File

@ -10,35 +10,8 @@ import ScrollableList from '../scrollable_list'
import TrendsItem from '../trends_item'
import TrendsItemPlaceholder from '../placeholder/trends_item_placeholder'
const messages = defineMessages({
title: { id: 'trends.title', defaultMessage: 'Trending right now' },
readMore: { id: 'status.read_more', defaultMessage: 'Read more' },
})
const mapStateToProps = (state) => ({
isError: state.getIn(['gab_trends', 'feed', 'isError']),
isLoading: state.getIn(['gab_trends', 'feed', 'isLoading']),
items: state.getIn(['gab_trends', 'feed', 'items']),
})
const mapDispatchToProps = (dispatch) => ({
onfetchGabTrends: () => dispatch(fetchGabTrends('feed')),
})
export default
@injectIntl
@connect(mapStateToProps, mapDispatchToProps)
class TrendsPanel extends ImmutablePureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
isError: PropTypes.bool,
isLazy: PropTypes.bool,
isLoading: PropTypes.bool,
items: ImmutablePropTypes.list.isRequired,
onfetchGabTrends: PropTypes.func.isRequired,
}
updateOnProps = [
'items',
'isLazy',
@ -116,4 +89,30 @@ class TrendsPanel extends ImmutablePureComponent {
</PanelLayout>
)
}
}
}
const messages = defineMessages({
title: { id: 'trends.title', defaultMessage: 'Trending right now' },
readMore: { id: 'status.read_more', defaultMessage: 'Read more' },
})
const mapStateToProps = (state) => ({
isError: state.getIn(['gab_trends', 'feed', 'isError']),
isLoading: state.getIn(['gab_trends', 'feed', 'isLoading']),
items: state.getIn(['gab_trends', 'feed', 'items']),
})
const mapDispatchToProps = (dispatch) => ({
onfetchGabTrends: () => dispatch(fetchGabTrends('feed')),
})
TrendsPanel.propTypes = {
intl: PropTypes.object.isRequired,
isError: PropTypes.bool,
isLazy: PropTypes.bool,
isLoading: PropTypes.bool,
items: ImmutablePropTypes.list.isRequired,
onfetchGabTrends: PropTypes.func.isRequired,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(TrendsPanel))

View File

@ -20,35 +20,8 @@ import DisplayName from '../display_name'
import Image from '../image'
import UserStat from '../user_stat'
const messages = defineMessages({
gabs: { id: 'account.posts', defaultMessage: 'Gabs' },
followers: { id: 'account.followers', defaultMessage: 'Followers' },
follows: { id: 'account.follows', defaultMessage: 'Following' },
edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' },
headerPhoto: { id: 'header_photo', defaultMessage: 'Header photo' },
})
const mapStateToProps = (state) => ({
account: makeGetAccount()(state, me),
})
const mapDispatchToProps = (dispatch) => ({
onOpenEditProfile() {
dispatch(openModal(MODAL_EDIT_PROFILE))
},
})
export default
@connect(mapStateToProps, mapDispatchToProps)
@injectIntl
class UserPanel extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map.isRequired,
intl: PropTypes.object.isRequired,
onOpenEditProfile: PropTypes.func.isRequired,
}
state = {
hovering: false,
}
@ -144,4 +117,31 @@ class UserPanel extends ImmutablePureComponent {
)
}
}
}
const messages = defineMessages({
gabs: { id: 'account.posts', defaultMessage: 'Gabs' },
followers: { id: 'account.followers', defaultMessage: 'Followers' },
follows: { id: 'account.follows', defaultMessage: 'Following' },
edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' },
headerPhoto: { id: 'header_photo', defaultMessage: 'Header photo' },
})
const mapStateToProps = (state) => ({
account: makeGetAccount()(state, me),
})
const mapDispatchToProps = (dispatch) => ({
onOpenEditProfile() {
dispatch(openModal(MODAL_EDIT_PROFILE))
},
})
UserPanel.propTypes = {
account: ImmutablePropTypes.map.isRequired,
intl: PropTypes.object.isRequired,
onOpenEditProfile: PropTypes.func.isRequired,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(UserPanel))

View File

@ -8,32 +8,8 @@ import ImmutablePropTypes from 'react-immutable-proptypes'
import Account from '../account'
import PanelLayout from './panel_layout'
const messages = defineMessages({
dismissSuggestion: { id: 'suggestions.dismiss', defaultMessage: 'Dismiss suggestion' },
title: { id: 'who_to_follow.title', defaultMessage: 'Verified Accounts to Follow' },
show_more: { id: 'who_to_follow.more', defaultMessage: 'Show more' },
})
const mapStateToProps = (state) => ({
suggestions: state.getIn(['suggestions', 'verified', 'items']),
})
const mapDispatchToProps = (dispatch) => ({
fetchPopularSuggestions: () => dispatch(fetchPopularSuggestions()),
})
export default
@connect(mapStateToProps, mapDispatchToProps)
@injectIntl
class VerifiedAccountsPanel extends ImmutablePureComponent {
static propTypes = {
fetchPopularSuggestions: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
suggestions: ImmutablePropTypes.list.isRequired,
isLazy: PropTypes.bool,
}
state = {
fetched: !this.props.isLazy,
}
@ -90,4 +66,27 @@ class VerifiedAccountsPanel extends ImmutablePureComponent {
</PanelLayout>
)
}
}
}
const messages = defineMessages({
dismissSuggestion: { id: 'suggestions.dismiss', defaultMessage: 'Dismiss suggestion' },
title: { id: 'who_to_follow.title', defaultMessage: 'Verified Accounts to Follow' },
show_more: { id: 'who_to_follow.more', defaultMessage: 'Show more' },
})
const mapStateToProps = (state) => ({
suggestions: state.getIn(['suggestions', 'verified', 'items']),
})
const mapDispatchToProps = (dispatch) => ({
fetchPopularSuggestions: () => dispatch(fetchPopularSuggestions()),
})
VerifiedAccountsPanel.propTypes = {
fetchPopularSuggestions: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
suggestions: ImmutablePropTypes.list.isRequired,
isLazy: PropTypes.bool,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(VerifiedAccountsPanel))

View File

@ -11,34 +11,8 @@ import Account from '../account'
import AccountPlaceholder from '../placeholder/account_placeholder'
import PanelLayout from './panel_layout'
const messages = defineMessages({
dismissSuggestion: { id: 'suggestions.dismiss', defaultMessage: 'Dismiss suggestion' },
title: { id: 'who_to_follow.title', defaultMessage: 'Who to Follow' },
show_more: { id: 'who_to_follow.more', defaultMessage: 'Show more' },
})
const mapStateToProps = (state) => ({
suggestions: state.getIn(['suggestions', 'related', 'items']),
isLoading: state.getIn(['suggestions', 'related', 'isLoading']),
})
const mapDispatchToProps = (dispatch) => ({
fetchRelatedSuggestions: () => dispatch(fetchRelatedSuggestions()),
})
export default
@connect(mapStateToProps, mapDispatchToProps)
@injectIntl
class WhoToFollowPanel extends ImmutablePureComponent {
static propTypes = {
fetchRelatedSuggestions: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
suggestions: ImmutablePropTypes.list.isRequired,
isLoading: PropTypes.bool.isRequired,
isLazy: PropTypes.bool,
}
state = {
fetched: !this.props.isLazy,
}
@ -103,4 +77,29 @@ class WhoToFollowPanel extends ImmutablePureComponent {
</PanelLayout>
)
}
}
}
const messages = defineMessages({
dismissSuggestion: { id: 'suggestions.dismiss', defaultMessage: 'Dismiss suggestion' },
title: { id: 'who_to_follow.title', defaultMessage: 'Who to Follow' },
show_more: { id: 'who_to_follow.more', defaultMessage: 'Show more' },
})
const mapStateToProps = (state) => ({
suggestions: state.getIn(['suggestions', 'related', 'items']),
isLoading: state.getIn(['suggestions', 'related', 'isLoading']),
})
const mapDispatchToProps = (dispatch) => ({
fetchRelatedSuggestions: () => dispatch(fetchRelatedSuggestions()),
})
WhoToFollowPanel.propTypes = {
fetchRelatedSuggestions: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
suggestions: ImmutablePropTypes.list.isRequired,
isLoading: PropTypes.bool.isRequired,
isLazy: PropTypes.bool,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(WhoToFollowPanel))

View File

@ -12,41 +12,8 @@ import {
import PopoverLayout from './popover_layout'
import List from '../list'
const messages = defineMessages({
oldest: { id: 'comment_sort.oldest', defaultMessage: 'Oldest' },
oldestSubtitle: { id: 'comment_sort.oldest.subtitle', defaultMessage: 'Show all comments, with the oldest comments first.' },
newest: { id: 'comment_sort.newest', defaultMessage: 'Recent' },
newestSubtitle: { id: 'comment_sort.newest.subtitle', defaultMessage: 'Show all comments, with the newest comments first.' },
top: { id: 'comment_sort.top', defaultMessage: 'Most Liked' },
topSubtitle: { id: 'comment_sort.top.subtitle', defaultMessage: 'Show all comments, with the most liked top-level comments first.' },
})
const mapStateToProps = (state) => ({
commentSorting: state.getIn(['settings', 'commentSorting']),
})
const mapDispatchToProps = (dispatch) => ({
onSetCommentSortingSetting(type) {
dispatch(changeSetting(['commentSorting'], type))
dispatch(saveSettings())
dispatch(closePopover())
},
onClosePopover: () => dispatch(closePopover()),
})
export default
@injectIntl
@connect(mapStateToProps, mapDispatchToProps)
class CommentSortingOptionsPopover extends React.PureComponent {
static propTypes = {
commentSorting: PropTypes.string.isRequired,
intl: PropTypes.object.isRequired,
isXS: PropTypes.bool,
onClosePopover: PropTypes.func.isRequired,
onSetCommentSortingSetting: PropTypes.func.isRequired,
}
handleOnClick = (type) => {
this.props.onSetCommentSortingSetting(type)
}
@ -100,4 +67,36 @@ class CommentSortingOptionsPopover extends React.PureComponent {
</PopoverLayout>
)
}
}
}
const messages = defineMessages({
oldest: { id: 'comment_sort.oldest', defaultMessage: 'Oldest' },
oldestSubtitle: { id: 'comment_sort.oldest.subtitle', defaultMessage: 'Show all comments, with the oldest comments first.' },
newest: { id: 'comment_sort.newest', defaultMessage: 'Recent' },
newestSubtitle: { id: 'comment_sort.newest.subtitle', defaultMessage: 'Show all comments, with the newest comments first.' },
top: { id: 'comment_sort.top', defaultMessage: 'Most Liked' },
topSubtitle: { id: 'comment_sort.top.subtitle', defaultMessage: 'Show all comments, with the most liked top-level comments first.' },
})
const mapStateToProps = (state) => ({
commentSorting: state.getIn(['settings', 'commentSorting']),
})
const mapDispatchToProps = (dispatch) => ({
onSetCommentSortingSetting(type) {
dispatch(changeSetting(['commentSorting'], type))
dispatch(saveSettings())
dispatch(closePopover())
},
onClosePopover: () => dispatch(closePopover()),
})
CommentSortingOptionsPopover.propTypes = {
commentSorting: PropTypes.string.isRequired,
intl: PropTypes.object.isRequired,
isXS: PropTypes.bool,
onClosePopover: PropTypes.func.isRequired,
onSetCommentSortingSetting: PropTypes.func.isRequired,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(CommentSortingOptionsPopover))

View File

@ -15,42 +15,8 @@ import Text from '../text'
import '!style-loader!css-loader!react-datepicker/dist/react-datepicker.css'
const mapStateToProps = (state) => ({
date: state.getIn(['compose', 'scheduled_at']),
isPro: state.getIn(['accounts', me, 'is_pro']),
})
const mapDispatchToProps = (dispatch) => ({
setScheduledAt (date, isPro) {
if (!isPro) {
dispatch(closePopover())
return dispatch(openModal(MODAL_PRO_UPGRADE))
}
dispatch(changeScheduledAt(date))
if (!date) {
dispatch(closePopover())
}
},
onClosePopover: () => dispatch(closePopover())
})
export default
@connect(mapStateToProps, mapDispatchToProps)
class DatePickerPopover extends React.PureComponent {
static propTypes = {
date: PropTypes.instanceOf(Date),
setScheduledAt: PropTypes.func.isRequired,
isPro: PropTypes.bool,
position: PropTypes.string,
small: PropTypes.bool,
isXS: PropTypes.bool,
onClosePopover: PropTypes.func.isRequired,
}
handleSetDate = (date) => {
this.props.setScheduledAt(date, this.props.isPro)
}
@ -127,4 +93,38 @@ class DatePickerPopover extends React.PureComponent {
)
}
}
}
const mapStateToProps = (state) => ({
date: state.getIn(['compose', 'scheduled_at']),
isPro: state.getIn(['accounts', me, 'is_pro']),
})
const mapDispatchToProps = (dispatch) => ({
setScheduledAt (date, isPro) {
if (!isPro) {
dispatch(closePopover())
return dispatch(openModal(MODAL_PRO_UPGRADE))
}
dispatch(changeScheduledAt(date))
if (!date) {
dispatch(closePopover())
}
},
onClosePopover: () => dispatch(closePopover())
})
DatePickerPopover.propTypes = {
date: PropTypes.instanceOf(Date),
setScheduledAt: PropTypes.func.isRequired,
isPro: PropTypes.bool,
position: PropTypes.string,
small: PropTypes.bool,
isXS: PropTypes.bool,
onClosePopover: PropTypes.func.isRequired,
}
export default connect(mapStateToProps, mapDispatchToProps)(DatePickerPopover)

View File

@ -109,27 +109,8 @@ const getCustomEmojis = createSelector([
return 0;
}));
@injectIntl
class EmojiPickerMenu extends ImmutablePureComponent {
static propTypes = {
customEmojis: ImmutablePropTypes.list,
frequentlyUsedEmojis: PropTypes.arrayOf(PropTypes.string),
loading: PropTypes.bool,
onClose: PropTypes.func.isRequired,
onPick: PropTypes.func.isRequired,
arrowOffsetLeft: PropTypes.string,
arrowOffsetTop: PropTypes.string,
intl: PropTypes.object.isRequired,
skinTone: PropTypes.number.isRequired,
onSkinTone: PropTypes.func.isRequired,
}
static defaultProps = {
loading: true,
frequentlyUsedEmojis: [],
}
getI18n = () => {
const { intl } = this.props
@ -209,42 +190,28 @@ class EmojiPickerMenu extends ImmutablePureComponent {
}
const mapStateToProps = (state) => ({
customEmojis: getCustomEmojis(state),
skinTone: state.getIn(['settings', 'skinTone']),
frequentlyUsedEmojis: getFrequentlyUsedEmojis(state),
})
EmojiPickerMenu.propTypes = {
customEmojis: ImmutablePropTypes.list,
frequentlyUsedEmojis: PropTypes.arrayOf(PropTypes.string),
loading: PropTypes.bool,
onClose: PropTypes.func.isRequired,
onPick: PropTypes.func.isRequired,
arrowOffsetLeft: PropTypes.string,
arrowOffsetTop: PropTypes.string,
intl: PropTypes.object.isRequired,
skinTone: PropTypes.number.isRequired,
onSkinTone: PropTypes.func.isRequired,
}
const mapDispatchToProps = (dispatch) => ({
onClosePopover() {
dispatch(closePopover())
},
EmojiPickerMenu.defaultProps = {
loading: true,
frequentlyUsedEmojis: [],
}
onSkinTone: (skinTone) => {
dispatch(changeSetting(['skinTone'], skinTone))
},
injectIntl(EmojiPickerMenu)
onPickEmoji: (emoji) => {
dispatch(useEmoji(emoji))
dispatch(insertEmojiCompose(emoji, false))
},
})
export default
@connect(mapStateToProps, mapDispatchToProps)
class EmojiPickerPopover extends ImmutablePureComponent {
static propTypes = {
customEmojis: ImmutablePropTypes.list,
frequentlyUsedEmojis: PropTypes.arrayOf(PropTypes.string),
intl: PropTypes.object.isRequired,
onPickEmoji: PropTypes.func.isRequired,
onSkinTone: PropTypes.func.isRequired,
skinTone: PropTypes.number.isRequired,
onClosePopover: PropTypes.func.isRequired,
isXS: PropTypes.bool,
}
state = {
loading: false,
}
@ -300,3 +267,37 @@ class EmojiPickerPopover extends ImmutablePureComponent {
}
}
const mapStateToProps = (state) => ({
customEmojis: getCustomEmojis(state),
skinTone: state.getIn(['settings', 'skinTone']),
frequentlyUsedEmojis: getFrequentlyUsedEmojis(state),
})
const mapDispatchToProps = (dispatch) => ({
onClosePopover() {
dispatch(closePopover())
},
onSkinTone: (skinTone) => {
dispatch(changeSetting(['skinTone'], skinTone))
},
onPickEmoji: (emoji) => {
dispatch(useEmoji(emoji))
dispatch(insertEmojiCompose(emoji, false))
},
})
EmojiPickerPopover.propTypes = {
customEmojis: ImmutablePropTypes.list,
frequentlyUsedEmojis: PropTypes.arrayOf(PropTypes.string),
intl: PropTypes.object.isRequired,
onPickEmoji: PropTypes.func.isRequired,
onSkinTone: PropTypes.func.isRequired,
skinTone: PropTypes.number.isRequired,
onClosePopover: PropTypes.func.isRequired,
isXS: PropTypes.bool,
}
export default connect(mapStateToProps, mapDispatchToProps)(EmojiPickerPopover)

View File

@ -3,12 +3,7 @@ import PropTypes from 'prop-types'
import PopoverLayout from './popover_layout'
import ColumnIndicator from '../column_indicator'
export default class ErrorPopover extends React.PureComponent {
static defaultProps = {
isXS: PropTypes.bool,
onClose: PropTypes.func,
}
class ErrorPopover extends React.PureComponent {
render() {
const { isXS } = this.props
@ -29,3 +24,10 @@ export default class ErrorPopover extends React.PureComponent {
}
}
ErrorPopover.defaultProps = {
isXS: PropTypes.bool,
onClose: PropTypes.func,
}
export default ErrorPopover

View File

@ -10,21 +10,8 @@ import {
import PopoverLayout from './popover_layout'
import List from '../list'
const mapDispatchToProps = (dispatch) => ({
onSortGroups: (tab, sortType) => dispatch(sortGroups(tab, sortType)),
onClosePopover:() => dispatch(closePopover()),
})
export default
@connect(null, mapDispatchToProps)
class GroupListSortOptionsPopover extends React.PureComponent {
static defaultProps = {
tab: PropTypes.string.isRequired,
onClosePopover: PropTypes.func.isRequired,
onSortGroups: PropTypes.func.isRequired,
}
handleOnSortGroup = (sortType) => {
this.props.onSortGroups(this.props.tab, sortType)
this.handleOnClosePopover()
@ -67,4 +54,17 @@ class GroupListSortOptionsPopover extends React.PureComponent {
)
}
}
}
const mapDispatchToProps = (dispatch) => ({
onSortGroups: (tab, sortType) => dispatch(sortGroups(tab, sortType)),
onClosePopover:() => dispatch(closePopover()),
})
GroupListSortOptionsPopover.defaultProps = {
tab: PropTypes.string.isRequired,
onClosePopover: PropTypes.func.isRequired,
onSortGroups: PropTypes.func.isRequired,
}
export default connect(null, mapDispatchToProps)(GroupListSortOptionsPopover)

View File

@ -9,31 +9,8 @@ import {
import PopoverLayout from './popover_layout'
import List from '../list'
const mapDispatchToProps = (dispatch) => ({
onUpdateRole(groupId, accountId, type) {
dispatch(closePopover())
dispatch(updateRole(groupId, accountId, type))
},
onCreateRemovedAccount(groupId, accountId) {
dispatch(closePopover())
dispatch(createRemovedAccount(groupId, accountId))
},
onClosePopover:() => dispatch(closePopover()),
})
export default
@connect(null, mapDispatchToProps)
class GroupMemberOptionsPopover extends React.PureComponent {
static defaultProps = {
accountId: PropTypes.string.isRequired,
groupId: PropTypes.string.isRequired,
isXS: PropTypes.bool,
onClosePopover: PropTypes.func.isRequired,
onCreateRemovedAccount: PropTypes.func.isRequired,
onUpdateRole: PropTypes.func.isRequired,
}
handleOnRemoveFromGroup = () => {
this.props.onCreateRemovedAccount(this.props.groupId, this.props.accountId)
}
@ -79,4 +56,27 @@ class GroupMemberOptionsPopover extends React.PureComponent {
)
}
}
}
const mapDispatchToProps = (dispatch) => ({
onUpdateRole(groupId, accountId, type) {
dispatch(closePopover())
dispatch(updateRole(groupId, accountId, type))
},
onCreateRemovedAccount(groupId, accountId) {
dispatch(closePopover())
dispatch(createRemovedAccount(groupId, accountId))
},
onClosePopover:() => dispatch(closePopover()),
})
GroupMemberOptionsPopover.defaultProps = {
accountId: PropTypes.string.isRequired,
groupId: PropTypes.string.isRequired,
isXS: PropTypes.bool,
onClosePopover: PropTypes.func.isRequired,
onCreateRemovedAccount: PropTypes.func.isRequired,
onUpdateRole: PropTypes.func.isRequired,
}
export default connect(null, mapDispatchToProps)(GroupMemberOptionsPopover)

View File

@ -12,49 +12,8 @@ import { closePopover } from '../../actions/popover'
import PopoverLayout from './popover_layout'
import List from '../list'
const messages = defineMessages({
groupMembers: { id: 'group_members', defaultMessage: 'Group members' },
removedMembers: { id: 'group_removed_members', defaultMessage: 'Removed accounts' },
editGroup: { id: 'edit_group', defaultMessage: 'Edit group' },
add_to_shortcuts: { id: 'account.add_to_shortcuts', defaultMessage: 'Add to shortcuts' },
remove_from_shortcuts: { id: 'account.remove_from_shortcuts', defaultMessage: 'Remove from shortcuts' },
})
const mapStateToProps = (state, { group }) => {
const groupId = group ? group.get('id') : null
const shortcuts = state.getIn(['shortcuts', 'items'])
const isShortcut = !!shortcuts.find((s) => {
return s.get('shortcut_id') == groupId && s.get('shortcut_type') === 'group'
})
return { isShortcut }
}
const mapDispatchToProps = (dispatch) => ({
onClosePopover: () => dispatch(closePopover()),
onAddShortcut(groupId) {
dispatch(addShortcut('group', groupId))
},
onRemoveShortcut(groupId) {
dispatch(removeShortcut(null, 'group', groupId))
},
})
export default
@injectIntl
@connect(mapStateToProps, mapDispatchToProps)
class GroupOptionsPopover extends ImmutablePureComponent {
static defaultProps = {
group: ImmutablePropTypes.map.isRequired,
isAdmin: PropTypes.bool,
intl: PropTypes.object.isRequired,
isXS: PropTypes.bool,
isShortcut: PropTypes.bool,
onAddShortcut: PropTypes.func.isRequired,
onRemoveShortcut: PropTypes.func.isRequired,
onClosePopover: PropTypes.func.isRequired,
}
handleOnClosePopover = () => {
this.props.onClosePopover()
}
@ -131,4 +90,44 @@ class GroupOptionsPopover extends ImmutablePureComponent {
)
}
}
}
const messages = defineMessages({
groupMembers: { id: 'group_members', defaultMessage: 'Group members' },
removedMembers: { id: 'group_removed_members', defaultMessage: 'Removed accounts' },
editGroup: { id: 'edit_group', defaultMessage: 'Edit group' },
add_to_shortcuts: { id: 'account.add_to_shortcuts', defaultMessage: 'Add to shortcuts' },
remove_from_shortcuts: { id: 'account.remove_from_shortcuts', defaultMessage: 'Remove from shortcuts' },
})
const mapStateToProps = (state, { group }) => {
const groupId = group ? group.get('id') : null
const shortcuts = state.getIn(['shortcuts', 'items'])
const isShortcut = !!shortcuts.find((s) => {
return s.get('shortcut_id') == groupId && s.get('shortcut_type') === 'group'
})
return { isShortcut }
}
const mapDispatchToProps = (dispatch) => ({
onClosePopover: () => dispatch(closePopover()),
onAddShortcut(groupId) {
dispatch(addShortcut('group', groupId))
},
onRemoveShortcut(groupId) {
dispatch(removeShortcut(null, 'group', groupId))
},
})
GroupOptionsPopover.defaultProps = {
group: ImmutablePropTypes.map.isRequired,
isAdmin: PropTypes.bool,
intl: PropTypes.object.isRequired,
isXS: PropTypes.bool,
isShortcut: PropTypes.bool,
onAddShortcut: PropTypes.func.isRequired,
onRemoveShortcut: PropTypes.func.isRequired,
onClosePopover: PropTypes.func.isRequired,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(GroupOptionsPopover))

View File

@ -14,43 +14,8 @@ import {
import PopoverLayout from './popover_layout'
import List from '../list'
const messages = defineMessages({
topTitle: { id: 'group_timeline_sorting.top_title', defaultMessage: 'Top Posts' },
topSubtitle: { id: 'group_timeline_sorting.top_subtitle', defaultMessage: 'See gabs with most comments, likes and reposts first' },
recentTitle: { id: 'group_timeline_sorting.recent_title', defaultMessage: 'Recent Activity' },
recentSubtitle: { id: 'group_timeline_sorting.recent_subtitle', defaultMessage: 'See gabs with most recent comments first' },
newTitle: { id: 'group_timeline_sorting.new_title', defaultMessage: 'New Posts' },
newSubtitle: { id: 'group_timeline_sorting.new_subtitle', defaultMessage: 'See most recent gabs first' },
hotTitle: { id: 'group_timeline_sorting.hot_title', defaultMessage: 'Hot Posts' },
hotSubtitle: { id: 'group_timeline_sorting.hot_subtitle', defaultMessage: 'See the most popular and recent gabs' },
})
const mapStateToProps = (state) => ({
sorting: state.getIn(['group_lists', 'sortByValue']),
})
const mapDispatchToProps = (dispatch) => ({
onSort(sort) {
dispatch(setGroupTimelineSort(sort))
dispatch(closePopover())
},
onClosePopover: () => dispatch(closePopover()),
})
export default
@injectIntl
@connect(mapStateToProps, mapDispatchToProps)
class GroupTimelineSortOptionsPopover extends React.PureComponent {
static propTypes = {
sorting: PropTypes.string.isRequired,
intl: PropTypes.object.isRequired,
isXS: PropTypes.bool,
onClosePopover: PropTypes.func.isRequired,
onSort: PropTypes.func.isRequired,
options: PropTypes.object.isRequired,
}
handleOnClick = (type) => {
this.props.onSort(type)
}
@ -117,4 +82,38 @@ class GroupTimelineSortOptionsPopover extends React.PureComponent {
</PopoverLayout>
)
}
}
}
const messages = defineMessages({
topTitle: { id: 'group_timeline_sorting.top_title', defaultMessage: 'Top Posts' },
topSubtitle: { id: 'group_timeline_sorting.top_subtitle', defaultMessage: 'See gabs with most comments, likes and reposts first' },
recentTitle: { id: 'group_timeline_sorting.recent_title', defaultMessage: 'Recent Activity' },
recentSubtitle: { id: 'group_timeline_sorting.recent_subtitle', defaultMessage: 'See gabs with most recent comments first' },
newTitle: { id: 'group_timeline_sorting.new_title', defaultMessage: 'New Posts' },
newSubtitle: { id: 'group_timeline_sorting.new_subtitle', defaultMessage: 'See most recent gabs first' },
hotTitle: { id: 'group_timeline_sorting.hot_title', defaultMessage: 'Hot Posts' },
hotSubtitle: { id: 'group_timeline_sorting.hot_subtitle', defaultMessage: 'See the most popular and recent gabs' },
})
const mapStateToProps = (state) => ({
sorting: state.getIn(['group_lists', 'sortByValue']),
})
const mapDispatchToProps = (dispatch) => ({
onSort(sort) {
dispatch(setGroupTimelineSort(sort))
dispatch(closePopover())
},
onClosePopover: () => dispatch(closePopover()),
})
GroupTimelineSortOptionsPopover.propTypes = {
sorting: PropTypes.string.isRequired,
intl: PropTypes.object.isRequired,
isXS: PropTypes.bool,
onClosePopover: PropTypes.func.isRequired,
onSort: PropTypes.func.isRequired,
options: PropTypes.object.isRequired,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(GroupTimelineSortOptionsPopover))

View File

@ -14,39 +14,8 @@ import {
import PopoverLayout from './popover_layout'
import List from '../list'
const messages = defineMessages({
topTodayTitle: { id: 'group_timeline_sorting.top_today_title', defaultMessage: 'Today' },
topWeekTitle: { id: 'group_timeline_sorting.top_week_title', defaultMessage: 'This Week' },
topMonthTitle: { id: 'group_timeline_sorting.top_month_title', defaultMessage: 'This Month' },
topYearTitle: { id: 'group_timeline_sorting.top_year_title', defaultMessage: 'This Year' },
topAllTitle: { id: 'group_timeline_sorting.top_all_title', defaultMessage: 'All Time' },
})
const mapStateToProps = (state) => ({
sortByTopValue: state.getIn(['group_lists', 'sortByTopValue']),
})
const mapDispatchToProps = (dispatch) => ({
onSort(sort) {
dispatch(setGroupTimelineTopSort(sort))
dispatch(closePopover())
},
onClosePopover: () => dispatch(closePopover()),
})
export default
@injectIntl
@connect(mapStateToProps, mapDispatchToProps)
class GroupTimelineSortTopOptionsPopover extends React.PureComponent {
static propTypes = {
sortByTopValue: PropTypes.string.isRequired,
intl: PropTypes.object.isRequired,
isXS: PropTypes.bool,
onClosePopover: PropTypes.func.isRequired,
onSort: PropTypes.func.isRequired,
}
handleOnClick = (type) => {
this.props.onSort(type)
}
@ -109,4 +78,34 @@ class GroupTimelineSortTopOptionsPopover extends React.PureComponent {
</PopoverLayout>
)
}
}
}
const messages = defineMessages({
topTodayTitle: { id: 'group_timeline_sorting.top_today_title', defaultMessage: 'Today' },
topWeekTitle: { id: 'group_timeline_sorting.top_week_title', defaultMessage: 'This Week' },
topMonthTitle: { id: 'group_timeline_sorting.top_month_title', defaultMessage: 'This Month' },
topYearTitle: { id: 'group_timeline_sorting.top_year_title', defaultMessage: 'This Year' },
topAllTitle: { id: 'group_timeline_sorting.top_all_title', defaultMessage: 'All Time' },
})
const mapStateToProps = (state) => ({
sortByTopValue: state.getIn(['group_lists', 'sortByTopValue']),
})
const mapDispatchToProps = (dispatch) => ({
onSort(sort) {
dispatch(setGroupTimelineTopSort(sort))
dispatch(closePopover())
},
onClosePopover: () => dispatch(closePopover()),
})
GroupTimelineSortTopOptionsPopover.propTypes = {
sortByTopValue: PropTypes.string.isRequired,
intl: PropTypes.object.isRequired,
isXS: PropTypes.bool,
onClosePopover: PropTypes.func.isRequired,
onSort: PropTypes.func.isRequired,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(GroupTimelineSortTopOptionsPopover))

View File

@ -3,12 +3,7 @@ import PropTypes from 'prop-types'
import PopoverLayout from './popover_layout'
import ColumnIndicator from '../column_indicator'
export default class LoadingPopover extends React.PureComponent {
static defaultProps = {
isXS: PropTypes.bool,
onClose: PropTypes.func,
}
class LoadingPopover extends React.PureComponent {
render() {
const { isXS } = this.props
@ -29,3 +24,10 @@ export default class LoadingPopover extends React.PureComponent {
}
}
LoadingPopover.defaultProps = {
isXS: PropTypes.bool,
onClose: PropTypes.func,
}
export default LoadingPopover

View File

@ -7,30 +7,7 @@ import { meUsername } from '../../initial_state'
import PopoverLayout from './popover_layout'
import List from '../list'
const messages = defineMessages({
profile: { id: 'account.profile', defaultMessage: 'Profile' },
display: { id: 'display_options', defaultMessage: 'Display Options' },
help: { id: 'getting_started.help', defaultMessage: 'Help' },
settings: { id: 'settings', defaultMessage: 'Settings' },
logout: { 'id': 'confirmations.logout.confirm', 'defaultMessage': 'Log out' },
})
const mapDispatchToProps = (dispatch) => ({
onClosePopover() {
dispatch(closePopover())
},
})
export default
@injectIntl
@connect(null, mapDispatchToProps)
class NavSettingsPopover extends React.PureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
onClosePopover: PropTypes.func.isRequired,
isXS: PropTypes.bool,
}
handleOnClosePopover = () => {
this.props.onClosePopover()
@ -69,4 +46,26 @@ class NavSettingsPopover extends React.PureComponent {
</PopoverLayout>
)
}
}
}
const messages = defineMessages({
profile: { id: 'account.profile', defaultMessage: 'Profile' },
display: { id: 'display_options', defaultMessage: 'Display Options' },
help: { id: 'getting_started.help', defaultMessage: 'Help' },
settings: { id: 'settings', defaultMessage: 'Settings' },
logout: { 'id': 'confirmations.logout.confirm', 'defaultMessage': 'Log out' },
})
const mapDispatchToProps = (dispatch) => ({
onClosePopover() {
dispatch(closePopover())
},
})
NavSettingsPopover.propTypes = {
intl: PropTypes.object.isRequired,
onClosePopover: PropTypes.func.isRequired,
isXS: PropTypes.bool,
}
export default injectIntl(connect(null, mapDispatchToProps)(NavSettingsPopover))

View File

@ -9,40 +9,12 @@ import { CX } from '../../constants'
const listenerOptions = detectPassiveEvents.hasSupport ? { passive: true } : false
const mapStateToProps = (state) => ({
isModalOpen: !!state.getIn(['modal', 'modalType']),
popoverPlacement: state.getIn(['popover', 'placement']),
})
export default
@connect(mapStateToProps)
class PopoverBase extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
}
static propTypes = {
title: PropTypes.string,
disabled: PropTypes.bool,
status: ImmutablePropTypes.map,
isUserTouching: PropTypes.func,
isModalOpen: PropTypes.bool.isRequired,
onClose: PropTypes.func.isRequired,
position: PropTypes.string,
visible: PropTypes.bool,
targetRef: PropTypes.node,
innerRef: PropTypes.oneOfType([
PropTypes.node,
PropTypes.func,
]),
}
static defaultProps = {
title: 'Menu',
position: 'bottom',
}
componentDidMount() {
document.addEventListener('click', this.handleDocumentClick, false)
document.addEventListener('keydown', this.handleKeyDown, false)
@ -154,3 +126,31 @@ class PopoverBase extends ImmutablePureComponent {
}
}
const mapStateToProps = (state) => ({
isModalOpen: !!state.getIn(['modal', 'modalType']),
popoverPlacement: state.getIn(['popover', 'placement']),
})
PopoverBase.propTypes = {
title: PropTypes.string,
disabled: PropTypes.bool,
status: ImmutablePropTypes.map,
isUserTouching: PropTypes.func,
isModalOpen: PropTypes.bool.isRequired,
onClose: PropTypes.func.isRequired,
position: PropTypes.string,
visible: PropTypes.bool,
targetRef: PropTypes.node,
innerRef: PropTypes.oneOfType([
PropTypes.node,
PropTypes.func,
]),
}
PopoverBase.defaultProps = {
title: 'Menu',
position: 'bottom',
}
export default connect(mapStateToProps)(PopoverBase)

View File

@ -5,19 +5,7 @@ import Button from '../button'
import Heading from '../heading'
import Text from '../text'
export default class PopoverLayout extends React.PureComponent {
static propTypes = {
children: PropTypes.node,
width: PropTypes.number,
isXS: PropTypes.bool,
title: PropTypes.string,
onClose: PropTypes.func,
}
static defaultProps = {
width: 250,
}
class PopoverLayout extends React.PureComponent {
handleOnClose = () => {
this.props.onClose()
@ -71,4 +59,18 @@ export default class PopoverLayout extends React.PureComponent {
)
}
}
}
PopoverLayout.propTypes = {
children: PropTypes.node,
width: PropTypes.number,
isXS: PropTypes.bool,
title: PropTypes.string,
onClose: PropTypes.func,
}
PopoverLayout.defaultProps = {
width: 250,
}
export default PopoverLayout

View File

@ -10,7 +10,6 @@ import {
POPOVER_GROUP_TIMELINE_SORT_TOP_OPTIONS,
POPOVER_NAV_SETTINGS,
POPOVER_PROFILE_OPTIONS,
POPOVER_SEARCH,
POPOVER_SIDEBAR_MORE,
POPOVER_STATUS_OPTIONS,
POPOVER_STATUS_EXPIRATION_OPTIONS,
@ -29,7 +28,6 @@ import {
GroupTimelineSortTopOptionsPopover,
NavSettingsPopover,
ProfileOptionsPopover,
SearchPopover,
SidebarMorePopover,
StatusExpirationOptionsPopover,
StatusOptionsPopover,
@ -62,7 +60,6 @@ POPOVER_COMPONENTS[POPOVER_GROUP_TIMELINE_SORT_OPTIONS] = GroupTimelineSortOptio
POPOVER_COMPONENTS[POPOVER_GROUP_TIMELINE_SORT_TOP_OPTIONS] = GroupTimelineSortTopOptionsPopover
POPOVER_COMPONENTS[POPOVER_NAV_SETTINGS] = NavSettingsPopover
POPOVER_COMPONENTS[POPOVER_PROFILE_OPTIONS] = ProfileOptionsPopover
POPOVER_COMPONENTS[POPOVER_SEARCH] = SearchPopover
POPOVER_COMPONENTS[POPOVER_SIDEBAR_MORE] = SidebarMorePopover
POPOVER_COMPONENTS[POPOVER_STATUS_OPTIONS] = StatusOptionsPopover
POPOVER_COMPONENTS[POPOVER_STATUS_EXPIRATION_OPTIONS] = StatusExpirationOptionsPopover
@ -70,25 +67,8 @@ POPOVER_COMPONENTS[POPOVER_STATUS_VISIBILITY] = StatusVisibilityPopover
POPOVER_COMPONENTS[POPOVER_USER_INFO] = UserInfoPopover
POPOVER_COMPONENTS[POPOVER_VIDEO_STATS] = VideoStatsPopover
const mapStateToProps = (state) => ({
type: state.getIn(['popover', 'popoverType']),
props: state.getIn(['popover', 'popoverProps'], {}),
})
const mapDispatchToProps = (dispatch) => ({
onClose: (type) => dispatch(closePopover(type)),
})
export default
@connect(mapStateToProps, mapDispatchToProps)
class PopoverRoot extends React.PureComponent {
static propTypes = {
type: PropTypes.string,
props: PropTypes.object,
onClose: PropTypes.func.isRequired,
}
state = {
width: initialState.width,
}
@ -170,4 +150,21 @@ class PopoverRoot extends React.PureComponent {
)
}
}
}
const mapStateToProps = (state) => ({
type: state.getIn(['popover', 'popoverType']),
props: state.getIn(['popover', 'popoverProps'], {}),
})
const mapDispatchToProps = (dispatch) => ({
onClose: (type) => dispatch(closePopover(type)),
})
PopoverRoot.propTypes = {
type: PropTypes.string,
props: PropTypes.object,
onClose: PropTypes.func.isRequired,
}
export default connect(mapStateToProps, mapDispatchToProps)(PopoverRoot)

View File

@ -23,127 +23,8 @@ import { makeGetAccount } from '../../selectors'
import PopoverLayout from './popover_layout'
import List from '../list'
const messages = defineMessages({
blockAndReport: { id: 'confirmations.block.block_and_report', defaultMessage: 'Block & Report' },
unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' },
follow: { id: 'account.follow', defaultMessage: 'Follow' },
requested: { id: 'account.requested', defaultMessage: 'Awaiting approval. Click to cancel follow request' },
unblock: { id: 'account.unblock', defaultMessage: 'Unblock @{name}' },
edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' },
linkVerifiedOn: { id: 'account.link_verified_on', defaultMessage: 'Ownership of this link was checked on {date}' },
account_locked: { id: 'account.locked_info', defaultMessage: 'This account privacy status is set to locked. The owner manually reviews who can follow them.' },
mention: { id: 'account.mention', defaultMessage: 'Mention' },
unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' },
block: { id: 'account.block', defaultMessage: 'Block @{name}' },
mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' },
report: { id: 'account.report', defaultMessage: 'Report @{name}' },
share: { id: 'account.share', defaultMessage: 'Share @{name}\'s profile' },
media: { id: 'account.media', defaultMessage: 'Media' },
hideReposts: { id: 'account.hide_reblogs', defaultMessage: 'Hide reposts from @{name}' },
showReposts: { id: 'account.show_reblogs', defaultMessage: 'Show reposts from @{name}' },
preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' },
mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' },
admin_account: { id: 'admin_account', defaultMessage: 'Open moderation interface' },
add_to_list: { id: 'lists.account.add', defaultMessage: 'Add to list' },
add_to_shortcuts: { id: 'account.add_to_shortcuts', defaultMessage: 'Add to shortcuts' },
remove_from_shortcuts: { id: 'account.remove_from_shortcuts', defaultMessage: 'Remove from shortcuts' },
accountBlocked: { id: 'account.blocked', defaultMessage: 'Blocked' },
accountMuted: { id: 'account.muted', defaultMessage: 'Muted' },
});
const mapStateToProps = (state, { account }) => {
const getAccount = makeGetAccount()
const accountId = !!account ? account.get('id') : -1
const shortcuts = state.getIn(['shortcuts', 'items'])
const isShortcut = !!shortcuts.find((s) => {
return s.get('shortcut_id') == accountId && s.get('shortcut_type') === 'account'
})
return {
isShortcut,
account: getAccount(state, accountId),
}
}
const mapDispatchToProps = (dispatch, { intl }) => ({
onFollow(account) {
if (account.getIn(['relationship', 'following']) || account.getIn(['relationship', 'requested'])) {
if (unfollowModal) {
dispatch(openModal('UNFOLLOW', {
account,
}))
} else {
dispatch(unfollowAccount(account.get('id')))
}
} else {
dispatch(followAccount(account.get('id')))
}
},
onBlock(account) {
dispatch(closePopover())
if (account.getIn(['relationship', 'blocking'])) {
dispatch(unblockAccount(account.get('id')));
} else {
dispatch(openModal('BLOCK_ACCOUNT', {
accountId: account.get('id'),
}));
}
},
onMention(account) {
dispatch(closePopover())
dispatch(mentionCompose(account));
},
onRepostToggle(account) {
dispatch(closePopover())
if (account.getIn(['relationship', 'showing_reblogs'])) {
dispatch(followAccount(account.get('id'), false));
} else {
dispatch(followAccount(account.get('id'), true));
}
},
onReport(account) {
dispatch(closePopover())
dispatch(initReport(account));
},
onMute(account) {
dispatch(closePopover())
if (account.getIn(['relationship', 'muting'])) {
dispatch(unmuteAccount(account.get('id')));
} else {
dispatch(openModal('MUTE', {
accountId: account.get('id'),
}))
}
},
onAddToList(account) {
dispatch(closePopover())
dispatch(openModal('LIST_ADD_USER', {
accountId: account.get('id'),
}));
},
onClosePopover: () => dispatch(closePopover()),
onAddShortcut(accountId) {
dispatch(closePopover())
dispatch(addShortcut('account', accountId))
},
onRemoveShortcut(accountId) {
dispatch(closePopover())
dispatch(removeShortcut(null, 'account', accountId))
},
})
export default
@injectIntl
@connect(mapStateToProps, mapDispatchToProps)
class ProfileOptionsPopover extends React.PureComponent {
static defaultProps = {
isXS: PropTypes.bool,
isShortcut: PropTypes.bool,
}
makeMenu() {
const {
account,
@ -299,4 +180,122 @@ class ProfileOptionsPopover extends React.PureComponent {
</PopoverLayout>
)
}
}
}
const messages = defineMessages({
blockAndReport: { id: 'confirmations.block.block_and_report', defaultMessage: 'Block & Report' },
unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' },
follow: { id: 'account.follow', defaultMessage: 'Follow' },
requested: { id: 'account.requested', defaultMessage: 'Awaiting approval. Click to cancel follow request' },
unblock: { id: 'account.unblock', defaultMessage: 'Unblock @{name}' },
edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' },
linkVerifiedOn: { id: 'account.link_verified_on', defaultMessage: 'Ownership of this link was checked on {date}' },
account_locked: { id: 'account.locked_info', defaultMessage: 'This account privacy status is set to locked. The owner manually reviews who can follow them.' },
mention: { id: 'account.mention', defaultMessage: 'Mention' },
unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' },
block: { id: 'account.block', defaultMessage: 'Block @{name}' },
mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' },
report: { id: 'account.report', defaultMessage: 'Report @{name}' },
share: { id: 'account.share', defaultMessage: 'Share @{name}\'s profile' },
media: { id: 'account.media', defaultMessage: 'Media' },
hideReposts: { id: 'account.hide_reblogs', defaultMessage: 'Hide reposts from @{name}' },
showReposts: { id: 'account.show_reblogs', defaultMessage: 'Show reposts from @{name}' },
preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' },
mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' },
admin_account: { id: 'admin_account', defaultMessage: 'Open moderation interface' },
add_to_list: { id: 'lists.account.add', defaultMessage: 'Add to list' },
add_to_shortcuts: { id: 'account.add_to_shortcuts', defaultMessage: 'Add to shortcuts' },
remove_from_shortcuts: { id: 'account.remove_from_shortcuts', defaultMessage: 'Remove from shortcuts' },
accountBlocked: { id: 'account.blocked', defaultMessage: 'Blocked' },
accountMuted: { id: 'account.muted', defaultMessage: 'Muted' },
});
const mapStateToProps = (state, { account }) => {
const getAccount = makeGetAccount()
const accountId = !!account ? account.get('id') : -1
const shortcuts = state.getIn(['shortcuts', 'items'])
const isShortcut = !!shortcuts.find((s) => {
return s.get('shortcut_id') == accountId && s.get('shortcut_type') === 'account'
})
return {
isShortcut,
account: getAccount(state, accountId),
}
}
const mapDispatchToProps = (dispatch, { intl }) => ({
onFollow(account) {
if (account.getIn(['relationship', 'following']) || account.getIn(['relationship', 'requested'])) {
if (unfollowModal) {
dispatch(openModal('UNFOLLOW', {
account,
}))
} else {
dispatch(unfollowAccount(account.get('id')))
}
} else {
dispatch(followAccount(account.get('id')))
}
},
onBlock(account) {
dispatch(closePopover())
if (account.getIn(['relationship', 'blocking'])) {
dispatch(unblockAccount(account.get('id')));
} else {
dispatch(openModal('BLOCK_ACCOUNT', {
accountId: account.get('id'),
}));
}
},
onMention(account) {
dispatch(closePopover())
dispatch(mentionCompose(account));
},
onRepostToggle(account) {
dispatch(closePopover())
if (account.getIn(['relationship', 'showing_reblogs'])) {
dispatch(followAccount(account.get('id'), false));
} else {
dispatch(followAccount(account.get('id'), true));
}
},
onReport(account) {
dispatch(closePopover())
dispatch(initReport(account));
},
onMute(account) {
dispatch(closePopover())
if (account.getIn(['relationship', 'muting'])) {
dispatch(unmuteAccount(account.get('id')));
} else {
dispatch(openModal('MUTE', {
accountId: account.get('id'),
}))
}
},
onAddToList(account) {
dispatch(closePopover())
dispatch(openModal('LIST_ADD_USER', {
accountId: account.get('id'),
}));
},
onClosePopover: () => dispatch(closePopover()),
onAddShortcut(accountId) {
dispatch(closePopover())
dispatch(addShortcut('account', accountId))
},
onRemoveShortcut(accountId) {
dispatch(closePopover())
dispatch(removeShortcut(null, 'account', accountId))
},
})
ProfileOptionsPopover.defaultProps = {
isXS: PropTypes.bool,
isShortcut: PropTypes.bool,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(ProfileOptionsPopover))

View File

@ -1,48 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
export default class SearchPopover extends React.PureComponent {
render() {
// : todo :
// <div className='search-popout-container' style={{ ...style, position: 'absolute', zIndex: 1000 }}>
// <Motion defaultStyle={{ opacity: 0, scaleX: 1, scaleY: 1 }} style={{ opacity: spring(1, { damping: 35, stiffness: 400 }), scaleX: spring(1, { damping: 35, stiffness: 400 }), scaleY: spring(1, { damping: 35, stiffness: 400 }) }}>
// {({ opacity, scaleX, scaleY }) => (
// <div className='search-popout' style={{ opacity: opacity, transform: `scale(${scaleX}, ${scaleY})` }}>
// <h4>
// <FormattedMessage id='search_popout.search_format' defaultMessage='Advanced search format' />
// </h4>
// <ul>
// <li>
// <em>#example</em>
// <FormattedMessage id='search_popout.tips.hashtag' defaultMessage='hashtag' />
// </li>
// <li>
// <em>@username</em>
// <FormattedMessage id='search_popout.tips.user' defaultMessage='user' />
// </li>
// <li>
// <em>URL</em>
// <FormattedMessage id='search_popout.tips.user' defaultMessage='user' />
// </li>
// <li>
// <em>URL</em>
// <FormattedMessage id='search_popout.tips.status' defaultMessage='status' />
// </li>
// </ul>
// {
// searchEnabled
// ? <FormattedMessage id='search_popout.tips.full_text' defaultMessage='Simple text returns statuses you have written, favorited, reposted, or have been mentioned in, as well as matching usernames, display names, and hashtags.' />
// : <FormattedMessage id='search_popout.tips.text' defaultMessage='Simple text returns matching display names, usernames and hashtags' />
// }
// </div>
// )}
// </Motion>
// </div>
return (
<div>
{ /* */}
</div>
)
}
}

View File

@ -8,32 +8,7 @@ import { closePopover } from '../../actions/popover'
import PopoverLayout from './popover_layout'
import List from '../list'
const messages = defineMessages({
display: { id: 'display_options', defaultMessage: 'Display Options' },
help: { id: 'getting_started.help', defaultMessage: 'Help' },
settings: { id: 'settings', defaultMessage: 'Settings' },
logout: { 'id': 'confirmations.logout.confirm', 'defaultMessage': 'Log out' },
blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' },
mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' },
})
const mapDispatchToProps = (dispatch) => ({
onOpenDisplayModal: () => {
dispatch(closePopover())
dispatch(openModal(MODAL_DISPLAY_OPTIONS))
},
})
export default
@injectIntl
@connect(null, mapDispatchToProps)
class SidebarMorePopover extends React.PureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
onOpenDisplayModal: PropTypes.func.isRequired,
isXS: PropTypes.bool,
}
handleOnOpenDisplayModal = () => {
this.props.onOpenDisplayModal()
@ -79,4 +54,28 @@ class SidebarMorePopover extends React.PureComponent {
</PopoverLayout>
)
}
}
}
const messages = defineMessages({
display: { id: 'display_options', defaultMessage: 'Display Options' },
help: { id: 'getting_started.help', defaultMessage: 'Help' },
settings: { id: 'settings', defaultMessage: 'Settings' },
logout: { 'id': 'confirmations.logout.confirm', 'defaultMessage': 'Log out' },
blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' },
mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' },
})
const mapDispatchToProps = (dispatch) => ({
onOpenDisplayModal: () => {
dispatch(closePopover())
dispatch(openModal(MODAL_DISPLAY_OPTIONS))
},
})
SidebarMorePopover.propTypes = {
intl: PropTypes.object.isRequired,
onOpenDisplayModal: PropTypes.func.isRequired,
isXS: PropTypes.bool,
}
export default injectIntl(connect(null, mapDispatchToProps)(SidebarMorePopover))

View File

@ -15,37 +15,8 @@ import {
import PopoverLayout from './popover_layout'
import List from '../list'
const messages = defineMessages({
minutes: { id: 'intervals.full.minutes', defaultMessage: '{number, plural, one {# minute} other {# minutes}}' },
hours: { id: 'intervals.full.hours', defaultMessage: '{number, plural, one {# hour} other {# hours}}' },
days: { id: 'intervals.full.days', defaultMessage: '{number, plural, one {# day} other {# days}}' },
})
const mapStateToProps = (state) => ({
expiresAtValue: state.getIn(['compose', 'expires_at']),
})
const mapDispatchToProps = (dispatch) => ({
onChangeExpiresAt(expiresAt) {
dispatch(changeExpiresAt(expiresAt))
},
onClosePopover() {
dispatch(closePopover())
},
})
export default
@injectIntl
@connect(mapStateToProps, mapDispatchToProps)
class StatusExpirationOptionsPopover extends React.PureComponent {
static defaultProps = {
expiresAtValue: PropTypes.string.isRequired,
intl: PropTypes.object.isRequired,
isXS: PropTypes.bool,
onChangeExpiresAt: PropTypes.func.isRequired,
}
handleOnSetStatusExpiration = (expiresAt) => {
this.props.onChangeExpiresAt(expiresAt)
this.handleOnClosePopover()
@ -126,4 +97,32 @@ class StatusExpirationOptionsPopover extends React.PureComponent {
)
}
}
}
const messages = defineMessages({
minutes: { id: 'intervals.full.minutes', defaultMessage: '{number, plural, one {# minute} other {# minutes}}' },
hours: { id: 'intervals.full.hours', defaultMessage: '{number, plural, one {# hour} other {# hours}}' },
days: { id: 'intervals.full.days', defaultMessage: '{number, plural, one {# day} other {# days}}' },
})
const mapStateToProps = (state) => ({
expiresAtValue: state.getIn(['compose', 'expires_at']),
})
const mapDispatchToProps = (dispatch) => ({
onChangeExpiresAt(expiresAt) {
dispatch(changeExpiresAt(expiresAt))
},
onClosePopover() {
dispatch(closePopover())
},
})
StatusExpirationOptionsPopover.defaultProps = {
expiresAtValue: PropTypes.string.isRequired,
intl: PropTypes.object.isRequired,
isXS: PropTypes.bool,
onChangeExpiresAt: PropTypes.func.isRequired,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(StatusExpirationOptionsPopover))

View File

@ -36,214 +36,11 @@ import {
import PopoverLayout from './popover_layout'
import List from '../list'
const messages = defineMessages({
delete: { id: 'status.delete', defaultMessage: 'Delete' },
edit: { id: 'status.edit', defaultMessage: 'Edit' },
mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' },
block: { id: 'account.block', defaultMessage: 'Block @{name}' },
reply: { id: 'status.reply', defaultMessage: 'Reply' },
more: { id: 'status.more', defaultMessage: 'More' },
share: { id: 'status.share', defaultMessage: 'Share' },
replyAll: { id: 'status.replyAll', defaultMessage: 'Reply to thread' },
repost: { id: 'repost', defaultMessage: 'Repost' },
quote: { id: 'status.quote', defaultMessage: 'Quote' },
repost_private: { id: 'status.repost', defaultMessage: 'Repost' },
cancel_repost_private: { id: 'status.cancel_repost_private', defaultMessage: 'Remove Repost' },
cannot_repost: { id: 'status.cannot_repost', defaultMessage: 'This post cannot be reposted' },
cannot_quote: { id: 'status.cannot_quote', defaultMessage: 'This post cannot be quoted' },
like: { id: 'status.like', defaultMessage: 'Like' },
report: { id: 'status.report', defaultMessage: 'Report @{name}' },
muteConversation: { id: 'status.mute_conversation', defaultMessage: 'Mute conversation' },
unmuteConversation: { id: 'status.unmute_conversation', defaultMessage: 'Unmute conversation' },
pin: { id: 'status.pin', defaultMessage: 'Pin on profile' },
unpin: { id: 'status.unpin', defaultMessage: 'Unpin from profile' },
bookmark: { id: 'status.bookmark', defaultMessage: 'Bookmark status' },
unbookmark: { id: 'status.unbookmark', defaultMessage: 'Remove bookmark' },
admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
admin_status: { id: 'status.admin_status', defaultMessage: 'Open this status in the moderation interface' },
group_remove_account: { id: 'status.remove_account_from_group', defaultMessage: 'Remove account from group' },
group_remove_post: { id: 'status.remove_post_from_group', defaultMessage: 'Remove status from group' },
repostWithComment: { id: 'repost_with_comment', defaultMessage: 'Repost with comment' },
embed: { id: 'status.embed', defaultMessage: 'Embed' },
email: { id: 'status.email', defaultMessage: 'Email this gab' },
copy: { id: 'status.copy', defaultMessage: 'Copy link to status' },
})
const mapStateToProps = (state, { status }) => {
if (!me) return null
const groupId = status ? status.getIn(['group', 'id']) : undefined
const groupRelationships = state.getIn(['group_relationships', groupId])
return {
groupId,
groupRelationships,
isPro: state.getIn(['accounts', me, 'is_pro']),
}
}
const mapDispatchToProps = (dispatch) => ({
onMuteConversation(status) {
dispatch(closePopover())
if (status.get('muted')) {
dispatch(unmuteStatus(status.get('id')))
} else {
dispatch(muteStatus(status.get('id')))
}
},
onPin(status) {
dispatch(closePopover())
if (status.get('pinned')) {
dispatch(unpin(status))
} else {
dispatch(pin(status))
}
},
onBookmark(status) {
dispatch(closePopover())
if (status.get('bookmarked')) {
dispatch(unbookmark(status))
} else {
dispatch(bookmark(status))
}
},
onQuote(status, router) {
dispatch(closePopover())
dispatch((_, getState) => {
const state = getState()
if (state.getIn(['compose', 'text']).trim().length !== 0) {
dispatch(openModal(MODAL_CONFIRM, {
message: intl.formatMessage(messages.quoteMessage),
confirm: intl.formatMessage(messages.quoteConfirm),
onConfirm: () => dispatch(quoteCompose(status, router)),
}))
} else {
dispatch(quoteCompose(status, router))
}
})
},
onRepost(status) {
dispatch(closePopover())
const alreadyReposted = status.get('reblogged')
if (boostModal && !alreadyReposted) {
dispatch(openModal(MODAL_BOOST, {
status,
onRepost: () => dispatch(repost(status)),
}))
} else {
if (alreadyReposted) {
dispatch(unrepost(status))
} else {
dispatch(repost(status))
}
}
},
onDelete(status, history) {
dispatch(closePopover())
if (!deleteModal) {
dispatch(deleteStatus(status.get('id'), history))
} else {
dispatch(openModal('CONFIRM', {
message: <FormattedMessage id='confirmations.delete.message' defaultMessage='Are you sure you want to delete this status?' />,
confirm: <FormattedMessage id='confirmations.delete.confirm' defaultMessage='Delete' />,
onConfirm: () => dispatch(deleteStatus(status.get('id'), history)),
}))
}
},
onEdit(status) {
dispatch(closePopover())
dispatch(editStatus(status))
},
onMute(account) {
dispatch(closePopover())
dispatch(initMuteModal(account))
},
onBlock(status) {
dispatch(closePopover())
const account = status.get('account')
dispatch(openModal('BLOCK_ACCOUNT', {
accountId: account.get('id'),
}))
},
onReport(status) {
dispatch(closePopover())
dispatch(initReport(status.get('account'), status))
},
onGroupRemoveAccount(groupId, accountId) {
dispatch(closePopover())
dispatch(createRemovedAccount(groupId, accountId))
},
onGroupRemoveStatus(groupId, statusId) {
dispatch(closePopover())
dispatch(groupRemoveStatus(groupId, statusId))
},
onFetchGroupRelationships(groupId) {
dispatch(fetchGroupRelationships([groupId]))
},
onOpenEmbedModal(url) {
dispatch(closePopover())
dispatch(openModal(MODAL_EMBED, {
url,
}))
},
onOpenProUpgradeModal() {
dispatch(closePopover())
dispatch(openModal(MODAL_PRO_UPGRADE))
},
onClosePopover: () => dispatch(closePopover()),
})
export default
@injectIntl
@connect(mapStateToProps, mapDispatchToProps)
class StatusOptionsPopover extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
}
static propTypes = {
status: ImmutablePropTypes.map.isRequired,
groupRelationships: ImmutablePropTypes.map,
groupId: PropTypes.string,
onQuote: PropTypes.func.isRequired,
onRepost: PropTypes.func.isRequired,
onDelete: PropTypes.func.isRequired,
onMute: PropTypes.func.isRequired,
onBlock: PropTypes.func.isRequired,
onReport: PropTypes.func.isRequired,
onMuteConversation: PropTypes.func.isRequired,
onPin: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
onFetchGroupRelationships: PropTypes.func.isRequired,
onOpenEmbedModal: PropTypes.func.isRequired,
onOpenProUpgradeModal: PropTypes.func.isRequired,
onClosePopover: PropTypes.func.isRequired,
isXS: PropTypes.bool,
isPro: PropTypes.bool,
}
updateOnProps = [
'status',
@ -496,4 +293,206 @@ class StatusOptionsPopover extends ImmutablePureComponent {
)
}
}
}
const messages = defineMessages({
delete: { id: 'status.delete', defaultMessage: 'Delete' },
edit: { id: 'status.edit', defaultMessage: 'Edit' },
mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' },
block: { id: 'account.block', defaultMessage: 'Block @{name}' },
reply: { id: 'status.reply', defaultMessage: 'Reply' },
more: { id: 'status.more', defaultMessage: 'More' },
share: { id: 'status.share', defaultMessage: 'Share' },
replyAll: { id: 'status.replyAll', defaultMessage: 'Reply to thread' },
repost: { id: 'repost', defaultMessage: 'Repost' },
quote: { id: 'status.quote', defaultMessage: 'Quote' },
repost_private: { id: 'status.repost', defaultMessage: 'Repost' },
cancel_repost_private: { id: 'status.cancel_repost_private', defaultMessage: 'Remove Repost' },
cannot_repost: { id: 'status.cannot_repost', defaultMessage: 'This post cannot be reposted' },
cannot_quote: { id: 'status.cannot_quote', defaultMessage: 'This post cannot be quoted' },
like: { id: 'status.like', defaultMessage: 'Like' },
report: { id: 'status.report', defaultMessage: 'Report @{name}' },
muteConversation: { id: 'status.mute_conversation', defaultMessage: 'Mute conversation' },
unmuteConversation: { id: 'status.unmute_conversation', defaultMessage: 'Unmute conversation' },
pin: { id: 'status.pin', defaultMessage: 'Pin on profile' },
unpin: { id: 'status.unpin', defaultMessage: 'Unpin from profile' },
bookmark: { id: 'status.bookmark', defaultMessage: 'Bookmark status' },
unbookmark: { id: 'status.unbookmark', defaultMessage: 'Remove bookmark' },
admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
admin_status: { id: 'status.admin_status', defaultMessage: 'Open this status in the moderation interface' },
group_remove_account: { id: 'status.remove_account_from_group', defaultMessage: 'Remove account from group' },
group_remove_post: { id: 'status.remove_post_from_group', defaultMessage: 'Remove status from group' },
repostWithComment: { id: 'repost_with_comment', defaultMessage: 'Repost with comment' },
embed: { id: 'status.embed', defaultMessage: 'Embed' },
email: { id: 'status.email', defaultMessage: 'Email this gab' },
copy: { id: 'status.copy', defaultMessage: 'Copy link to status' },
})
const mapStateToProps = (state, { status }) => {
if (!me) return null
const groupId = status ? status.getIn(['group', 'id']) : undefined
const groupRelationships = state.getIn(['group_relationships', groupId])
return {
groupId,
groupRelationships,
isPro: state.getIn(['accounts', me, 'is_pro']),
}
}
const mapDispatchToProps = (dispatch) => ({
onMuteConversation(status) {
dispatch(closePopover())
if (status.get('muted')) {
dispatch(unmuteStatus(status.get('id')))
} else {
dispatch(muteStatus(status.get('id')))
}
},
onPin(status) {
dispatch(closePopover())
if (status.get('pinned')) {
dispatch(unpin(status))
} else {
dispatch(pin(status))
}
},
onBookmark(status) {
dispatch(closePopover())
if (status.get('bookmarked')) {
dispatch(unbookmark(status))
} else {
dispatch(bookmark(status))
}
},
onQuote(status, router) {
dispatch(closePopover())
dispatch((_, getState) => {
const state = getState()
if (state.getIn(['compose', 'text']).trim().length !== 0) {
dispatch(openModal(MODAL_CONFIRM, {
message: intl.formatMessage(messages.quoteMessage),
confirm: intl.formatMessage(messages.quoteConfirm),
onConfirm: () => dispatch(quoteCompose(status, router)),
}))
} else {
dispatch(quoteCompose(status, router))
}
})
},
onRepost(status) {
dispatch(closePopover())
const alreadyReposted = status.get('reblogged')
if (boostModal && !alreadyReposted) {
dispatch(openModal(MODAL_BOOST, {
status,
onRepost: () => dispatch(repost(status)),
}))
} else {
if (alreadyReposted) {
dispatch(unrepost(status))
} else {
dispatch(repost(status))
}
}
},
onDelete(status, history) {
dispatch(closePopover())
if (!deleteModal) {
dispatch(deleteStatus(status.get('id'), history))
} else {
dispatch(openModal('CONFIRM', {
message: <FormattedMessage id='confirmations.delete.message' defaultMessage='Are you sure you want to delete this status?' />,
confirm: <FormattedMessage id='confirmations.delete.confirm' defaultMessage='Delete' />,
onConfirm: () => dispatch(deleteStatus(status.get('id'), history)),
}))
}
},
onEdit(status) {
dispatch(closePopover())
dispatch(editStatus(status))
},
onMute(account) {
dispatch(closePopover())
dispatch(initMuteModal(account))
},
onBlock(status) {
dispatch(closePopover())
const account = status.get('account')
dispatch(openModal('BLOCK_ACCOUNT', {
accountId: account.get('id'),
}))
},
onReport(status) {
dispatch(closePopover())
dispatch(initReport(status.get('account'), status))
},
onGroupRemoveAccount(groupId, accountId) {
dispatch(closePopover())
dispatch(createRemovedAccount(groupId, accountId))
},
onGroupRemoveStatus(groupId, statusId) {
dispatch(closePopover())
dispatch(groupRemoveStatus(groupId, statusId))
},
onFetchGroupRelationships(groupId) {
dispatch(fetchGroupRelationships([groupId]))
},
onOpenEmbedModal(url) {
dispatch(closePopover())
dispatch(openModal(MODAL_EMBED, {
url,
}))
},
onOpenProUpgradeModal() {
dispatch(closePopover())
dispatch(openModal(MODAL_PRO_UPGRADE))
},
onClosePopover: () => dispatch(closePopover()),
})
StatusOptionsPopover.propTypes = {
status: ImmutablePropTypes.map.isRequired,
groupRelationships: ImmutablePropTypes.map,
groupId: PropTypes.string,
onQuote: PropTypes.func.isRequired,
onRepost: PropTypes.func.isRequired,
onDelete: PropTypes.func.isRequired,
onMute: PropTypes.func.isRequired,
onBlock: PropTypes.func.isRequired,
onReport: PropTypes.func.isRequired,
onMuteConversation: PropTypes.func.isRequired,
onPin: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
onFetchGroupRelationships: PropTypes.func.isRequired,
onOpenEmbedModal: PropTypes.func.isRequired,
onOpenProUpgradeModal: PropTypes.func.isRequired,
onClosePopover: PropTypes.func.isRequired,
isXS: PropTypes.bool,
isPro: PropTypes.bool,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(StatusOptionsPopover))

View File

@ -11,42 +11,8 @@ import Text from '../text'
const cx = classNames.bind(_s)
const messages = defineMessages({
public_short: { id: 'privacy.public.short', defaultMessage: 'Public' },
public_long: { id: 'privacy.public.long', defaultMessage: 'Visible for anyone on or off Gab' },
unlisted_short: { id: 'privacy.unlisted.short', defaultMessage: 'Unlisted' },
unlisted_long: { id: 'privacy.unlisted.long', defaultMessage: 'Do not show in public timelines' },
private_short: { id: 'privacy.private.short', defaultMessage: 'Followers-only' },
private_long: { id: 'privacy.private.long', defaultMessage: 'Visible for your followers only' },
change_privacy: { id: 'privacy.change', defaultMessage: 'Adjust status privacy' },
visibility: { id: 'privacy.visibility', defaultMessage: 'Visibility' },
})
const mapStateToProps = (state) => ({
value: state.getIn(['compose', 'privacy']),
})
const mapDispatchToProps = (dispatch) => ({
onChange (value) {
dispatch(changeComposeVisibility(value))
dispatch(closePopover())
},
onClosePopover: () => dispatch(closePopover()),
})
export default
@connect(mapStateToProps, mapDispatchToProps)
@injectIntl
class StatusVisibilityDropdown extends React.PureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
isXS: PropTypes.bool,
onChange: PropTypes.func.isRequired,
onClosePopover: PropTypes.func.isRequired,
value: PropTypes.string.isRequired,
}
handleChange = (value) => {
this.props.onChange(value)
}
@ -135,4 +101,35 @@ class StatusVisibilityDropdown extends React.PureComponent {
}
const messages = defineMessages({
public_short: { id: 'privacy.public.short', defaultMessage: 'Public' },
public_long: { id: 'privacy.public.long', defaultMessage: 'Visible for anyone on or off Gab' },
unlisted_short: { id: 'privacy.unlisted.short', defaultMessage: 'Unlisted' },
unlisted_long: { id: 'privacy.unlisted.long', defaultMessage: 'Do not show in public timelines' },
private_short: { id: 'privacy.private.short', defaultMessage: 'Followers-only' },
private_long: { id: 'privacy.private.long', defaultMessage: 'Visible for your followers only' },
change_privacy: { id: 'privacy.change', defaultMessage: 'Adjust status privacy' },
visibility: { id: 'privacy.visibility', defaultMessage: 'Visibility' },
})
const mapStateToProps = (state) => ({
value: state.getIn(['compose', 'privacy']),
})
const mapDispatchToProps = (dispatch) => ({
onChange (value) {
dispatch(changeComposeVisibility(value))
dispatch(closePopover())
},
onClosePopover: () => dispatch(closePopover()),
})
StatusVisibilityDropdown.propTypes = {
intl: PropTypes.object.isRequired,
isXS: PropTypes.bool,
onChange: PropTypes.func.isRequired,
onClosePopover: PropTypes.func.isRequired,
value: PropTypes.string.isRequired,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(StatusVisibilityDropdown))

View File

@ -14,20 +14,8 @@ import Avatar from '../avatar'
import DisplayName from '../display_name'
import Text from '../text'
const mapStateToProps = (state, props) => ({
account: makeGetAccount()(state, props.accountId),
})
export default
@connect(mapStateToProps)
class UserInfoPopover extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map,
accountId: PropTypes.string.isRequired,
isXS: PropTypes.bool,
}
render() {
const { account, isXS } = this.props
@ -87,4 +75,16 @@ class UserInfoPopover extends ImmutablePureComponent {
</PopoverLayout>
)
}
}
}
const mapStateToProps = (state, props) => ({
account: makeGetAccount()(state, props.accountId),
})
UserInfoPopover.propTypes = {
account: ImmutablePropTypes.map,
accountId: PropTypes.string.isRequired,
isXS: PropTypes.bool,
}
export default connect(mapStateToProps)(UserInfoPopover)

View File

@ -10,35 +10,8 @@ import PopoverLayout from './popover_layout'
import Button from '../button'
import Text from '../text'
const messages = defineMessages({
size: { id: 'size', defaultMessage: 'Size' },
audio_bitrate: { id: 'video.audio_bitrate', defaultMessage: 'Audio Bitrate' },
fps: { id: 'fps', defaultMessage: 'FPS' },
aspect: { id: 'video.aspect_ratio', defaultMessage: 'Aspect Ratio' },
audio_channels: { id: 'video.audio_channels', defaultMessage: 'Audio Channels' },
audio_encode: { id: 'video.audio_encode', defaultMessage: 'Audio Encode' },
original_height: { id: 'video.original_height', defaultMessage: 'Original Height' },
original_width: { id: 'video.original_width', defaultMessage: 'Original Width' },
original_frame_rate: { id: 'video.original_frame_rate', defaultMessage: 'Original Frame Rate' },
original_bitrate: { id: 'video.original_bitrate', defaultMessage: 'Original Bitrate' },
})
const mapDispatchToProps = (dispatch) => ({
onClosePopover: () => dispatch(closePopover()),
})
export default
@injectIntl
@connect(null, mapDispatchToProps)
class VideoStatsPopover extends ImmutablePureComponent {
static propTypes = {
meta: ImmutablePropTypes.map.isRequired,
onClosePopover: PropTypes.func.isRequired,
isXS: PropTypes.bool,
intl: PropTypes.object.isRequired,
}
updateOnProps = [
'meta',
'isXS',
@ -125,12 +98,6 @@ class VideoStatsPopover extends ImmutablePureComponent {
class VideoStatLine extends React.PureComponent {
static propTypes = {
isXS: PropTypes.bool.isRequired,
title: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
}
render() {
const { isXS, title, value } = this.props
@ -150,4 +117,36 @@ class VideoStatLine extends React.PureComponent {
)
}
}
}
VideoStatLine.propTypes = {
isXS: PropTypes.bool.isRequired,
title: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
}
const messages = defineMessages({
size: { id: 'size', defaultMessage: 'Size' },
audio_bitrate: { id: 'video.audio_bitrate', defaultMessage: 'Audio Bitrate' },
fps: { id: 'fps', defaultMessage: 'FPS' },
aspect: { id: 'video.aspect_ratio', defaultMessage: 'Aspect Ratio' },
audio_channels: { id: 'video.audio_channels', defaultMessage: 'Audio Channels' },
audio_encode: { id: 'video.audio_encode', defaultMessage: 'Audio Encode' },
original_height: { id: 'video.original_height', defaultMessage: 'Original Height' },
original_width: { id: 'video.original_width', defaultMessage: 'Original Width' },
original_frame_rate: { id: 'video.original_frame_rate', defaultMessage: 'Original Frame Rate' },
original_bitrate: { id: 'video.original_bitrate', defaultMessage: 'Original Bitrate' },
})
const mapDispatchToProps = (dispatch) => ({
onClosePopover: () => dispatch(closePopover()),
})
VideoStatsPopover.propTypes = {
meta: ImmutablePropTypes.map.isRequired,
onClosePopover: PropTypes.func.isRequired,
isXS: PropTypes.bool,
intl: PropTypes.object.isRequired,
}
export default injectIntl(connect(null, mapDispatchToProps)(VideoStatsPopover))

View File

@ -122,14 +122,6 @@ class RichTextEditorBar extends React.PureComponent {
class StyleButton extends React.PureComponent {
static propTypes = {
onClick: PropTypes.func,
label: PropTypes.string,
style: PropTypes.string,
icon: PropTypes.string,
type: PropTypes.string,
}
handleOnClick = (e) => {
e.preventDefault()
this.props.onClick(this.props.style, this.props.type)
@ -179,6 +171,14 @@ class StyleButton extends React.PureComponent {
}
StyleButton.propTypes = {
onClick: PropTypes.func,
label: PropTypes.string,
style: PropTypes.string,
icon: PropTypes.string,
type: PropTypes.string,
}
const mapStateToProps = (state) => {
const getAccount = makeGetAccount()
const account = getAccount(state, me)

View File

@ -14,12 +14,7 @@ addLocaleData(localeData);
const MEDIA_COMPONENTS = { MediaGallery, Video, Card, Poll };
export default class MediaContainer extends React.PureComponent {
static propTypes = {
locale: PropTypes.string.isRequired,
components: PropTypes.object.isRequired,
};
class MediaContainer extends React.PureComponent {
state = {
media: null,
@ -77,4 +72,11 @@ export default class MediaContainer extends React.PureComponent {
);
}
}
}
MediaContainer.propTypes = {
locale: PropTypes.string.isRequired,
components: PropTypes.object.isRequired,
}
export default MediaContainer

View File

@ -12,44 +12,8 @@ import LoadMore from '../components/load_more'
import Block from '../components/block'
import MediaGalleryPlaceholder from '../components/placeholder/media_gallery_placeholder'
const messages = defineMessages({
none: { id: 'account_gallery.none', defaultMessage: 'No media to show.' },
})
const mapStateToProps = (state, { account, mediaType }) => {
const accountId = !!account ? account.get('id') : -1
return {
accountId,
attachments: getAccountGallery(state, accountId, mediaType),
isLoading: state.getIn(['timelines', `account:${accountId}:media`, 'isLoading']),
hasMore: state.getIn(['timelines', `account:${accountId}:media`, 'hasMore']),
}
}
export default
@connect(mapStateToProps)
@injectIntl
class AccountGallery extends ImmutablePureComponent {
static propTypes = {
dispatch: PropTypes.func.isRequired,
account: ImmutablePropTypes.map,
accountId: PropTypes.string,
attachments: ImmutablePropTypes.list.isRequired,
isLoading: PropTypes.bool,
hasMore: PropTypes.bool,
intl: PropTypes.object.isRequired,
mediaType: PropTypes.oneOf([
'photo',
'video',
]),
}
static defaultProps = {
mediaType: 'both'
}
componentDidMount() {
const { accountId, mediaType } = this.props
@ -149,3 +113,38 @@ class AccountGallery extends ImmutablePureComponent {
}
}
const messages = defineMessages({
none: { id: 'account_gallery.none', defaultMessage: 'No media to show.' },
})
const mapStateToProps = (state, { account, mediaType }) => {
const accountId = !!account ? account.get('id') : -1
return {
accountId,
attachments: getAccountGallery(state, accountId, mediaType),
isLoading: state.getIn(['timelines', `account:${accountId}:media`, 'isLoading']),
hasMore: state.getIn(['timelines', `account:${accountId}:media`, 'hasMore']),
}
}
AccountGallery.propTypes = {
dispatch: PropTypes.func.isRequired,
account: ImmutablePropTypes.map,
accountId: PropTypes.string,
attachments: ImmutablePropTypes.list.isRequired,
isLoading: PropTypes.bool,
hasMore: PropTypes.bool,
intl: PropTypes.object.isRequired,
mediaType: PropTypes.oneOf([
'photo',
'video',
]),
}
AccountGallery.defaultProps = {
mediaType: 'both'
}
export default injectIntl(connect(mapStateToProps)(AccountGallery))

View File

@ -8,42 +8,8 @@ import { injectIntl, defineMessages } from 'react-intl'
import { expandAccountFeaturedTimeline, expandAccountTimeline } from '../actions/timelines'
import StatusList from '../components/status_list'
const messages = defineMessages({
empty: { id: 'empty_column.account_timeline', defaultMessage: 'No gabs here!' },
})
const emptyList = ImmutableList()
const mapStateToProps = (state, { account, commentsOnly = false }) => {
const accountId = !!account ? account.getIn(['id'], null) : -1
const path = commentsOnly ? `${accountId}:comments_only` : accountId
return {
accountId,
statusIds: state.getIn(['timelines', `account:${path}`, 'items'], emptyList),
featuredStatusIds: commentsOnly ? ImmutableList() : state.getIn(['timelines', `account:${accountId}:pinned`, 'items'], emptyList),
isLoading: state.getIn(['timelines', `account:${path}`, 'isLoading'], true),
hasMore: state.getIn(['timelines', `account:${path}`, 'hasMore']),
}
}
export default
@connect(mapStateToProps)
@injectIntl
class AccountTimeline extends ImmutablePureComponent {
static propTypes = {
params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
statusIds: ImmutablePropTypes.list,
featuredStatusIds: ImmutablePropTypes.list,
isLoading: PropTypes.bool,
hasMore: PropTypes.bool,
commentsOnly: PropTypes.bool,
intl: PropTypes.object.isRequired,
}
componentWillMount() {
const { accountId, commentsOnly } = this.props
@ -98,3 +64,36 @@ class AccountTimeline extends ImmutablePureComponent {
}
}
const messages = defineMessages({
empty: { id: 'empty_column.account_timeline', defaultMessage: 'No gabs here!' },
})
const emptyList = ImmutableList()
const mapStateToProps = (state, { account, commentsOnly = false }) => {
const accountId = !!account ? account.getIn(['id'], null) : -1
const path = commentsOnly ? `${accountId}:comments_only` : accountId
return {
accountId,
statusIds: state.getIn(['timelines', `account:${path}`, 'items'], emptyList),
featuredStatusIds: commentsOnly ? ImmutableList() : state.getIn(['timelines', `account:${accountId}:pinned`, 'items'], emptyList),
isLoading: state.getIn(['timelines', `account:${path}`, 'isLoading'], true),
hasMore: state.getIn(['timelines', `account:${path}`, 'hasMore']),
}
}
AccountTimeline.propTypes = {
params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
statusIds: ImmutablePropTypes.list,
featuredStatusIds: ImmutablePropTypes.list,
isLoading: PropTypes.bool,
hasMore: PropTypes.bool,
commentsOnly: PropTypes.bool,
intl: PropTypes.object.isRequired,
}
export default injectIntl(connect(mapStateToProps)(AccountTimeline))

View File

@ -12,36 +12,8 @@ import Block from '../components/block'
import BlockHeading from '../components/block_heading'
import ScrollableList from '../components/scrollable_list'
const messages = defineMessages({
empty: { id: 'empty_column.blocks', defaultMessage: 'You haven\'t blocked any users yet.' },
blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' },
})
const mapStateToProps = (state) => ({
accountIds: state.getIn(['user_lists', 'blocks', me, 'items']),
hasMore: !!state.getIn(['user_lists', 'blocks', me, 'next']),
isLoading: state.getIn(['user_lists', 'blocks', me, 'isLoading']),
})
const mapDispatchToProps = (dispatch) => ({
onFetchBlocks: () => dispatch(fetchBlocks()),
onExpandBlocks: () => dispatch(expandBlocks()),
})
export default
@connect(mapStateToProps, mapDispatchToProps)
@injectIntl
class Blocks extends ImmutablePureComponent {
static propTypes = {
accountIds: ImmutablePropTypes.list,
hasMore: PropTypes.bool,
intl: PropTypes.object.isRequired,
isLoading: PropTypes.bool,
onExpandBlocks: PropTypes.func.isRequired,
onFetchBlocks: PropTypes.func.isRequired,
}
componentDidMount() {
this.props.onFetchBlocks()
}
@ -85,3 +57,30 @@ class Blocks extends ImmutablePureComponent {
}
}
const messages = defineMessages({
empty: { id: 'empty_column.blocks', defaultMessage: 'You haven\'t blocked any users yet.' },
blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' },
})
const mapStateToProps = (state) => ({
accountIds: state.getIn(['user_lists', 'blocks', me, 'items']),
hasMore: !!state.getIn(['user_lists', 'blocks', me, 'next']),
isLoading: state.getIn(['user_lists', 'blocks', me, 'isLoading']),
})
const mapDispatchToProps = (dispatch) => ({
onFetchBlocks: () => dispatch(fetchBlocks()),
onExpandBlocks: () => dispatch(expandBlocks()),
})
Blocks.propTypes = {
accountIds: ImmutablePropTypes.list,
hasMore: PropTypes.bool,
intl: PropTypes.object.isRequired,
isLoading: PropTypes.bool,
onExpandBlocks: PropTypes.func.isRequired,
onFetchBlocks: PropTypes.func.isRequired,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(Blocks))

View File

@ -10,27 +10,8 @@ import { meUsername } from '../initial_state'
import StatusList from '../components/status_list'
import ColumnIndicator from '../components/column_indicator'
const mapStateToProps = (state, { params: { username } }) => {
return {
isMyAccount: (username.toLowerCase() === meUsername.toLowerCase()),
statusIds: state.getIn(['status_lists', 'bookmarks', 'items']),
isLoading: state.getIn(['status_lists', 'bookmarks', 'isLoading'], true),
hasMore: !!state.getIn(['status_lists', 'bookmarks', 'next']),
}
}
export default
@connect(mapStateToProps)
class BookmarkedStatuses extends ImmutablePureComponent {
static propTypes = {
dispatch: PropTypes.func.isRequired,
statusIds: ImmutablePropTypes.list.isRequired,
hasMore: PropTypes.bool,
isLoading: PropTypes.bool,
isMyAccount: PropTypes.bool.isRequired,
}
componentWillMount() {
this.props.dispatch(fetchBookmarkedStatuses())
}
@ -65,3 +46,21 @@ class BookmarkedStatuses extends ImmutablePureComponent {
}
const mapStateToProps = (state, { params: { username } }) => {
return {
isMyAccount: (username.toLowerCase() === meUsername.toLowerCase()),
statusIds: state.getIn(['status_lists', 'bookmarks', 'items']),
isLoading: state.getIn(['status_lists', 'bookmarks', 'isLoading'], true),
hasMore: !!state.getIn(['status_lists', 'bookmarks', 'next']),
}
}
BookmarkedStatuses.propTypes = {
dispatch: PropTypes.func.isRequired,
statusIds: ImmutablePropTypes.list.isRequired,
hasMore: PropTypes.bool,
isLoading: PropTypes.bool,
isMyAccount: PropTypes.bool.isRequired,
}
export default connect(mapStateToProps)(BookmarkedStatuses)

View File

@ -5,29 +5,12 @@ import { defineMessages, injectIntl } from 'react-intl'
import { expandCommunityTimeline } from '../actions/timelines'
import StatusList from '../components/status_list'
const messages = defineMessages({
empty: { id: 'empty_column.community', defaultMessage: 'The community timeline is empty. Write something publicly to get the ball rolling!' },
})
const mapStateToProps = (state) => ({
onlyMedia: state.getIn(['settings', 'community', 'other', 'onlyMedia'])
})
export default
@connect(mapStateToProps)
@injectIntl
class CommunityTimeline extends React.PureComponent {
static contextTypes = {
router: PropTypes.object,
}
static propTypes = {
dispatch: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
onlyMedia: PropTypes.bool,
}
componentDidMount () {
const { dispatch, onlyMedia } = this.props
@ -64,3 +47,19 @@ class CommunityTimeline extends React.PureComponent {
}
}
const messages = defineMessages({
empty: { id: 'empty_column.community', defaultMessage: 'The community timeline is empty. Write something publicly to get the ball rolling!' },
})
const mapStateToProps = (state) => ({
onlyMedia: state.getIn(['settings', 'community', 'other', 'onlyMedia'])
})
CommunityTimeline.propTypes = {
dispatch: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
onlyMedia: PropTypes.bool,
}
export default injectIntl(connect(mapStateToProps)(CommunityTimeline))

View File

@ -200,7 +200,6 @@ class ComposeForm extends ImmutablePureComponent {
isMatch,
isChangingUpload,
isSubmitting,
selectedGifSrc,
isPro,
hidePro,
} = this.props
@ -390,19 +389,6 @@ class ComposeForm extends ImmutablePureComponent {
</div>
}
{
/* : todo :
!!selectedGifSrc && !anyMedia &&
<div className={[_s.d, _s.px15].join(' ')}>
<GifForm
replyToId={replyToId}
small={shouldCondense}
selectedGifSrc={selectedGifSrc}
/>
</div>
*/
}
{
!edit && hasPoll &&
<div className={[_s.d, _s.px15, _s.mt5].join(' ')}>
@ -518,7 +504,6 @@ ComposeForm.propTypes = {
replyToId: PropTypes.string,
reduxReplyToId: PropTypes.string,
hasPoll: PropTypes.bool,
selectedGifSrc: PropTypes.string,
isPro: PropTypes.bool,
hidePro: PropTypes.bool,
autoJoinGroup: PropTypes.bool,

View File

@ -1,45 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { clearSelectedGif } from '../../../actions/tenor'
import Image from '../../../components/image'
class GifForm extends React.PureComponent {
render () {
const {
selectedGifSrc,
small,
} = this.props
if (!selectedGifSrc) return null
return (
<div className={_s.d}>
<div className={[_s.d, _s.flexRow, _s.flexWrap].join(' ')}>
<Image
width='auto'
src={selectedGifSrc}
className={[_s.maxW100PC, _s.radiusSmall, _s.h260PX].join(' ')}
/>
</div>
</div>
)
}
}
const mapDispatchToProps = (dispatch) => ({
onClearSelectedGif() {
dispatch(clearSelectedGif())
},
})
GifForm.propTypes = {
onClearSelectedGif: PropTypes.func.isRequired,
replyToId: PropTypes.string,
small: PropTypes.bool,
selectedGifSrc: PropTypes.string.isRequired,
}
export default connect(null, mapDispatchToProps)(GifForm)

View File

@ -119,16 +119,6 @@ class PollForm extends ImmutablePureComponent {
class PollFormOption extends ImmutablePureComponent {
static propTypes = {
title: PropTypes.string.isRequired,
index: PropTypes.number.isRequired,
isPollMultiple: PropTypes.bool,
onChange: PropTypes.func.isRequired,
onRemove: PropTypes.func.isRequired,
onToggleMultiple: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
}
handleOptionTitleChange = (value) => {
this.props.onChange(this.props.index, value)
}
@ -195,6 +185,16 @@ class PollFormOption extends ImmutablePureComponent {
}
PollFormOption.propTypes = {
title: PropTypes.string.isRequired,
index: PropTypes.number.isRequired,
isPollMultiple: PropTypes.bool,
onChange: PropTypes.func.isRequired,
onRemove: PropTypes.func.isRequired,
onToggleMultiple: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
}
const messages = defineMessages({
option_placeholder: { id: 'compose_form.poll.option_placeholder', defaultMessage: 'Choice {number}' },
add_option: { id: 'compose_form.poll.add_option', defaultMessage: 'Add a choice' },

View File

@ -67,7 +67,6 @@ const mapStateToProps = (state, props) => {
scheduledAt: null,
account: state.getIn(['accounts', me]),
hasPoll: false,
selectedGifSrc: null,
}
}
@ -95,7 +94,6 @@ const mapStateToProps = (state, props) => {
account: state.getIn(['accounts', me]),
isPro: state.getIn(['accounts', me, 'is_pro']),
hasPoll: state.getIn(['compose', 'poll']),
selectedGifSrc: state.getIn(['tenor', 'selectedGif', 'src']),
}
}

View File

@ -12,35 +12,8 @@ import Block from '../components/block'
import ScrollableList from '../components/scrollable_list'
import Text from '../components/text'
const mapStateToProps = (state) => ({
accountIds: state.getIn(['user_lists', 'follow_requests', me, 'items']),
isLoading: state.getIn(['user_lists', 'follow_requests', me, 'isLoading']),
hasMore: !!state.getIn(['user_lists', 'follow_requests', me, 'next']),
locked: !!state.getIn(['accounts', me, 'locked']),
})
const mapDispatchToProps = (dispatch) => ({
onFetchFollowRequests() {
dispatch(fetchFollowRequests())
},
onExpandFollowRequests() {
dispatch(expandFollowRequests())
},
})
export default
@connect(mapStateToProps, mapDispatchToProps)
class FollowRequests extends ImmutablePureComponent {
static propTypes = {
accountIds: ImmutablePropTypes.list,
hasMore: PropTypes.bool,
isLoading: PropTypes.bool,
locked: PropTypes.bool,
onFetchFollowRequests: PropTypes.func.isRequired,
onExpandFollowRequests: PropTypes.func.isRequired,
}
componentWillMount () {
this.props.onFetchFollowRequests()
}
@ -91,3 +64,30 @@ class FollowRequests extends ImmutablePureComponent {
}
}
const mapStateToProps = (state) => ({
accountIds: state.getIn(['user_lists', 'follow_requests', me, 'items']),
isLoading: state.getIn(['user_lists', 'follow_requests', me, 'isLoading']),
hasMore: !!state.getIn(['user_lists', 'follow_requests', me, 'next']),
locked: !!state.getIn(['accounts', me, 'locked']),
})
const mapDispatchToProps = (dispatch) => ({
onFetchFollowRequests() {
dispatch(fetchFollowRequests())
},
onExpandFollowRequests() {
dispatch(expandFollowRequests())
},
})
FollowRequests.propTypes = {
accountIds: ImmutablePropTypes.list,
hasMore: PropTypes.bool,
isLoading: PropTypes.bool,
locked: PropTypes.bool,
onFetchFollowRequests: PropTypes.func.isRequired,
onExpandFollowRequests: PropTypes.func.isRequired,
}
export default connect(mapStateToProps, mapDispatchToProps)(FollowRequests)

View File

@ -15,38 +15,8 @@ import Block from '../components/block'
import BlockHeading from '../components/block_heading'
import AccountPlaceholder from '../components/placeholder/account_placeholder'
const mapStateToProps = (state, { account }) => {
const accountId = !!account ? account.get('id') : -1
return {
accountId,
accountIds: state.getIn(['user_lists', 'followers', accountId, 'items']),
hasMore: !!state.getIn(['user_lists', 'followers', accountId, 'next']),
isLoading: state.getIn(['user_lists', 'followers', accountId, 'isLoading'], true),
}
}
const messages = defineMessages({
followers: { id: 'account.followers', defaultMessage: 'Followers' },
empty: { id: 'account.followers.empty', defaultMessage: 'No one follows this user yet.' },
})
export default
@connect(mapStateToProps)
@injectIntl
class Followers extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map,
accountId: PropTypes.string,
intl: PropTypes.object.isRequired,
params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
accountIds: ImmutablePropTypes.list,
hasMore: PropTypes.bool,
isLoading: PropTypes.bool,
}
componentWillMount() {
const { accountId } = this.props
@ -101,3 +71,32 @@ class Followers extends ImmutablePureComponent {
}
}
const mapStateToProps = (state, { account }) => {
const accountId = !!account ? account.get('id') : -1
return {
accountId,
accountIds: state.getIn(['user_lists', 'followers', accountId, 'items']),
hasMore: !!state.getIn(['user_lists', 'followers', accountId, 'next']),
isLoading: state.getIn(['user_lists', 'followers', accountId, 'isLoading'], true),
}
}
const messages = defineMessages({
followers: { id: 'account.followers', defaultMessage: 'Followers' },
empty: { id: 'account.followers.empty', defaultMessage: 'No one follows this user yet.' },
})
Followers.propTypes = {
account: ImmutablePropTypes.map,
accountId: PropTypes.string,
intl: PropTypes.object.isRequired,
params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
accountIds: ImmutablePropTypes.list,
hasMore: PropTypes.bool,
isLoading: PropTypes.bool,
}
export default injectIntl(connect(mapStateToProps)(Followers))

View File

@ -15,38 +15,8 @@ import Block from '../components/block'
import BlockHeading from '../components/block_heading'
import AccountPlaceholder from '../components/placeholder/account_placeholder'
const mapStateToProps = (state, { account }) => {
const accountId = !!account ? account.get('id') : -1
return {
accountId,
accountIds: state.getIn(['user_lists', 'following', accountId, 'items']),
hasMore: !!state.getIn(['user_lists', 'following', accountId, 'next']),
isLoading: state.getIn(['user_lists', 'following', accountId, 'isLoading'], true),
}
}
const messages = defineMessages({
follows: { id: 'account.follows', defaultMessage: 'Following' },
empty: { id: 'account.follows.empty', defaultMessage: 'This user doesn\'t follow anyone yet.' },
})
export default
@connect(mapStateToProps)
@injectIntl
class Following extends ImmutablePureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
accountIds: ImmutablePropTypes.list,
account: ImmutablePropTypes.map,
accountId: PropTypes.string,
hasMore: PropTypes.bool,
isLoading: PropTypes.bool,
}
componentDidMount() {
const { accountId } = this.props
@ -100,4 +70,33 @@ class Following extends ImmutablePureComponent {
)
}
}
}
const mapStateToProps = (state, { account }) => {
const accountId = !!account ? account.get('id') : -1
return {
accountId,
accountIds: state.getIn(['user_lists', 'following', accountId, 'items']),
hasMore: !!state.getIn(['user_lists', 'following', accountId, 'next']),
isLoading: state.getIn(['user_lists', 'following', accountId, 'isLoading'], true),
}
}
const messages = defineMessages({
follows: { id: 'account.follows', defaultMessage: 'Following' },
empty: { id: 'account.follows.empty', defaultMessage: 'This user doesn\'t follow anyone yet.' },
})
Following.propTypes = {
intl: PropTypes.object.isRequired,
params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
accountIds: ImmutablePropTypes.list,
account: ImmutablePropTypes.map,
accountId: PropTypes.string,
hasMore: PropTypes.bool,
isLoading: PropTypes.bool,
}
export default injectIntl(connect(mapStateToProps)(Following))

View File

@ -12,25 +12,8 @@ import {
GroupInfoPanel
} from '../features/ui/util/async_components'
const mapStateToProps = (state, { params }) => {
const groupId = isObject(params) ? params['id'] : null
const group = state.getIn(['groups', groupId])
return { group }
}
export default
@connect(mapStateToProps)
class GroupAbout extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object
}
static propTypes = {
group: ImmutablePropTypes.map,
}
render() {
const { group } = this.props
@ -56,3 +39,16 @@ class GroupAbout extends ImmutablePureComponent {
}
}
const mapStateToProps = (state, { params }) => {
const groupId = isObject(params) ? params['id'] : null
const group = state.getIn(['groups', groupId])
return { group }
}
GroupAbout.propTypes = {
group: ImmutablePropTypes.map,
}
export default connect(mapStateToProps)(GroupAbout)

View File

@ -22,63 +22,8 @@ import StatusList from '../components/status_list'
import GroupSortBlock from '../components/group_sort_block'
import GroupsCollection from './groups_collection'
const messages = defineMessages({
empty: { id: 'empty_column.group_collection_timeline', defaultMessage: 'There are no gabs to display.' },
})
const mapStateToProps = (state) => {
let hasNoGroupMembers = true
try {
hasNoGroupMembers = state.getIn(['group_lists', 'member', 'items'], ImmutableList()).count() === 0
} catch (error) {
//
}
return {
hasNoGroupMembers,
sortByValue: state.getIn(['group_lists', 'sortByValue']),
sortByTopValue: state.getIn(['group_lists', 'sortByTopValue']),
}
}
const mapDispatchToProps = (dispatch) => ({
onConnectGroupCollectionStream(collectionType, sortBy) {
dispatch(connectGroupCollectionStream(collectionType, sortBy))
},
onClearTimeline(timeline) {
dispatch(clearTimeline(timeline))
},
onExpandGroupCollectionTimeline(collectionType, options) {
dispatch(expandGroupCollectionTimeline(collectionType, options))
},
setFeaturedTop() {
dispatch(setGroupTimelineSort(GROUP_TIMELINE_SORTING_TYPE_HOT))
},
setMemberNewest() {
dispatch(setGroupTimelineSort(GROUP_TIMELINE_SORTING_TYPE_NEWEST))
},
})
export default
@injectIntl
@connect(mapStateToProps, mapDispatchToProps)
class GroupCollectionTimeline extends React.PureComponent {
static propTypes = {
params: PropTypes.object.isRequired,
onConnectGroupCollectionStream: PropTypes.func.isRequired,
onClearTimeline: PropTypes.func.isRequired,
onExpandGroupCollectionTimeline: PropTypes.func.isRequired,
setFeaturedTop: PropTypes.func.isRequired,
setMemberNewest: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
collectionType: PropTypes.string.isRequired,
sortByValue: PropTypes.string.isRequired,
sortByTopValue: PropTypes.string,
hasStatuses: PropTypes.bool.isRequired,
}
state = {
//keep track of loads for if no user,
//only allow 2 loads before showing sign up msg
@ -184,3 +129,57 @@ class GroupCollectionTimeline extends React.PureComponent {
}
}
const messages = defineMessages({
empty: { id: 'empty_column.group_collection_timeline', defaultMessage: 'There are no gabs to display.' },
})
const mapStateToProps = (state) => {
let hasNoGroupMembers = true
try {
hasNoGroupMembers = state.getIn(['group_lists', 'member', 'items'], ImmutableList()).count() === 0
} catch (error) {
//
}
return {
hasNoGroupMembers,
sortByValue: state.getIn(['group_lists', 'sortByValue']),
sortByTopValue: state.getIn(['group_lists', 'sortByTopValue']),
}
}
const mapDispatchToProps = (dispatch) => ({
onConnectGroupCollectionStream(collectionType, sortBy) {
dispatch(connectGroupCollectionStream(collectionType, sortBy))
},
onClearTimeline(timeline) {
dispatch(clearTimeline(timeline))
},
onExpandGroupCollectionTimeline(collectionType, options) {
dispatch(expandGroupCollectionTimeline(collectionType, options))
},
setFeaturedTop() {
dispatch(setGroupTimelineSort(GROUP_TIMELINE_SORTING_TYPE_HOT))
},
setMemberNewest() {
dispatch(setGroupTimelineSort(GROUP_TIMELINE_SORTING_TYPE_NEWEST))
},
})
GroupCollectionTimeline.propTypes = {
params: PropTypes.object.isRequired,
onConnectGroupCollectionStream: PropTypes.func.isRequired,
onClearTimeline: PropTypes.func.isRequired,
onExpandGroupCollectionTimeline: PropTypes.func.isRequired,
setFeaturedTop: PropTypes.func.isRequired,
setMemberNewest: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
collectionType: PropTypes.string.isRequired,
sortByValue: PropTypes.string.isRequired,
sortByTopValue: PropTypes.string,
hasStatuses: PropTypes.bool.isRequired,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(GroupCollectionTimeline))

View File

@ -32,137 +32,12 @@ import Select from '../components/select'
import Textarea from '../components/textarea'
import FileInput from '../components/file_input'
const messages = defineMessages({
title: { id: 'groups.form.title', defaultMessage: 'Title' },
idTitle: { id: 'groups.form.id_title', defaultMessage: 'Unique id' },
idDescription: { id: 'groups.form.id_description', defaultMessage: 'A unique id that links to this group. (Cannot be changed)' },
tagsTitle: { id: 'groups.form.tags_title', defaultMessage: 'Tags' },
tagsDescription: { id: 'groups.form.tags_description', defaultMessage: 'Add tags seperated by commas to increase group visibility' },
categoryTitle: { id: 'groups.form.category_title', defaultMessage: 'Category' },
categoryDescription: { id: 'groups.form.category_description', defaultMessage: 'Add a general category for your group' },
description: { id: 'groups.form.description', defaultMessage: 'Enter the group description' },
coverImage: { id: 'groups.form.coverImage', defaultMessage: 'Upload a banner image' },
coverImageDescription: { id: 'groups.form.coverImage_description', defaultMessage: 'Accepted image types: .jpg, .png' },
coverImageChange: { id: 'groups.form.coverImageChange', defaultMessage: 'Banner image selected' },
create: { id: 'groups.form.create', defaultMessage: 'Create group' },
update: { id: 'groups.form.update', defaultMessage: 'Update group' },
titlePlaceholder: { id: 'groups.form.title_placeholder', defaultMessage: 'New group title...' },
descriptionPlaceholder: { id: 'groups.form.description_placeholder', defaultMessage: 'This group is about...' },
isPrivateDescription: { id: 'groups.form.is_private_description', defaultMessage: 'Only members can see group posts.' },
isVisibleDescription: { id: 'groups.form.is_visible_description', defaultMessage: 'Anyone can find a visible group in search and other places on Gab.' },
})
const mapStateToProps = (state, { params }) => {
const groupId = isObject(params) ? params['id'] : null
const group = state.getIn(['groups', groupId])
let isAdmin = false
if (groupId) {
const relationships = state.getIn(['group_relationships', groupId])
if (relationships) {
isAdmin = relationships.get('admin')
}
}
return {
group,
groupId,
isAdmin,
error: (groupId && !group) || (group && !isAdmin),
titleValue: state.getIn(['group_editor', 'title']),
descriptionValue: state.getIn(['group_editor', 'description']),
coverImage: state.getIn(['group_editor', 'coverImage']),
isSubmitting: state.getIn(['group_editor', 'isSubmitting']),
idValue: state.getIn(['group_editor', 'id']),
tags: state.getIn(['group_editor', 'tags']),
category: state.getIn(['group_editor', 'category']),
isPrivate: state.getIn(['group_editor', 'isPrivate']),
isVisible: state.getIn(['group_editor', 'isVisible']),
categories: state.getIn(['group_categories', 'items']),
}
}
const mapDispatchToProps = (dispatch) => ({
onTitleChange(value) {
dispatch(changeGroupTitle(value))
},
onDescriptionChange(value) {
dispatch(changeGroupDescription(value))
},
onCoverImageChange(imageData) {
dispatch(changeGroupCoverImage(imageData))
},
onChangeGroupId(value) {
dispatch(changeGroupId(value))
},
onChangeGroupTags(value) {
dispatch(changeGroupTags(value))
},
onChangeGroupCategory(e) {
dispatch(changeGroupCategory(e.target.value))
},
onChangeGroupIsPrivate(value) {
dispatch(changeGroupIsPrivate(value))
},
onChangeGroupIsVisible(value) {
dispatch(changeGroupIsVisible(value))
},
onResetEditor() {
dispatch(resetEditor())
},
onSetGroup(group) {
dispatch(setGroup(group))
},
onSubmit(routerHistory) {
dispatch(submit(routerHistory))
dispatch(closeModal())
},
onFetchGroup(groupId) {
dispatch(fetchGroup(groupId))
},
onFetchGroupCategories() {
dispatch(fetchGroupCategories())
}
})
export default
@injectIntl
@connect(mapStateToProps, mapDispatchToProps)
class GroupCreate extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object
}
static propTypes = {
group: ImmutablePropTypes.map,
titleValue: PropTypes.string.isRequired,
descriptionValue: PropTypes.string.isRequired,
coverImage: PropTypes.object,
intl: PropTypes.object.isRequired,
onTitleChange: PropTypes.func.isRequired,
onDescriptionChange: PropTypes.func.isRequired,
onChangeGroupId: PropTypes.func.isRequired,
onChangeGroupTags: PropTypes.func.isRequired,
onChangeGroupCategory: PropTypes.func.isRequired,
onChangeGroupIsPrivate: PropTypes.func.isRequired,
onChangeGroupIsVisible: PropTypes.func.isRequired,
onFetchGroup: PropTypes.func.isRequired,
onFetchGroupCategories: PropTypes.func.isRequired,
onResetEditor: PropTypes.func.isRequired,
onSetGroup: PropTypes.func.isRequired,
onSubmit: PropTypes.func.isRequired,
isSubmitting: PropTypes.bool,
isAdmin: PropTypes.bool,
onClose: PropTypes.func,
idValue: PropTypes.string.isRequired,
tags: PropTypes.string.isRequired,
category: PropTypes.string.isRequired,
isPrivate: PropTypes.bool.isRequired,
isVisible: PropTypes.bool.isRequired,
categories: ImmutablePropTypes.list.isRequired,
}
componentDidMount() {
const { groupId, group } = this.props
@ -374,3 +249,128 @@ class GroupCreate extends ImmutablePureComponent {
}
}
const messages = defineMessages({
title: { id: 'groups.form.title', defaultMessage: 'Title' },
idTitle: { id: 'groups.form.id_title', defaultMessage: 'Unique id' },
idDescription: { id: 'groups.form.id_description', defaultMessage: 'A unique id that links to this group. (Cannot be changed)' },
tagsTitle: { id: 'groups.form.tags_title', defaultMessage: 'Tags' },
tagsDescription: { id: 'groups.form.tags_description', defaultMessage: 'Add tags seperated by commas to increase group visibility' },
categoryTitle: { id: 'groups.form.category_title', defaultMessage: 'Category' },
categoryDescription: { id: 'groups.form.category_description', defaultMessage: 'Add a general category for your group' },
description: { id: 'groups.form.description', defaultMessage: 'Enter the group description' },
coverImage: { id: 'groups.form.coverImage', defaultMessage: 'Upload a banner image' },
coverImageDescription: { id: 'groups.form.coverImage_description', defaultMessage: 'Accepted image types: .jpg, .png' },
coverImageChange: { id: 'groups.form.coverImageChange', defaultMessage: 'Banner image selected' },
create: { id: 'groups.form.create', defaultMessage: 'Create group' },
update: { id: 'groups.form.update', defaultMessage: 'Update group' },
titlePlaceholder: { id: 'groups.form.title_placeholder', defaultMessage: 'New group title...' },
descriptionPlaceholder: { id: 'groups.form.description_placeholder', defaultMessage: 'This group is about...' },
isPrivateDescription: { id: 'groups.form.is_private_description', defaultMessage: 'Only members can see group posts.' },
isVisibleDescription: { id: 'groups.form.is_visible_description', defaultMessage: 'Anyone can find a visible group in search and other places on Gab.' },
})
const mapStateToProps = (state, { params }) => {
const groupId = isObject(params) ? params['id'] : null
const group = state.getIn(['groups', groupId])
let isAdmin = false
if (groupId) {
const relationships = state.getIn(['group_relationships', groupId])
if (relationships) {
isAdmin = relationships.get('admin')
}
}
return {
group,
groupId,
isAdmin,
error: (groupId && !group) || (group && !isAdmin),
titleValue: state.getIn(['group_editor', 'title']),
descriptionValue: state.getIn(['group_editor', 'description']),
coverImage: state.getIn(['group_editor', 'coverImage']),
isSubmitting: state.getIn(['group_editor', 'isSubmitting']),
idValue: state.getIn(['group_editor', 'id']),
tags: state.getIn(['group_editor', 'tags']),
category: state.getIn(['group_editor', 'category']),
isPrivate: state.getIn(['group_editor', 'isPrivate']),
isVisible: state.getIn(['group_editor', 'isVisible']),
categories: state.getIn(['group_categories', 'items']),
}
}
const mapDispatchToProps = (dispatch) => ({
onTitleChange(value) {
dispatch(changeGroupTitle(value))
},
onDescriptionChange(value) {
dispatch(changeGroupDescription(value))
},
onCoverImageChange(imageData) {
dispatch(changeGroupCoverImage(imageData))
},
onChangeGroupId(value) {
dispatch(changeGroupId(value))
},
onChangeGroupTags(value) {
dispatch(changeGroupTags(value))
},
onChangeGroupCategory(e) {
dispatch(changeGroupCategory(e.target.value))
},
onChangeGroupIsPrivate(value) {
dispatch(changeGroupIsPrivate(value))
},
onChangeGroupIsVisible(value) {
dispatch(changeGroupIsVisible(value))
},
onResetEditor() {
dispatch(resetEditor())
},
onSetGroup(group) {
dispatch(setGroup(group))
},
onSubmit(routerHistory) {
dispatch(submit(routerHistory))
dispatch(closeModal())
},
onFetchGroup(groupId) {
dispatch(fetchGroup(groupId))
},
onFetchGroupCategories() {
dispatch(fetchGroupCategories())
}
})
GroupCreate.propTypes = {
group: ImmutablePropTypes.map,
titleValue: PropTypes.string.isRequired,
descriptionValue: PropTypes.string.isRequired,
coverImage: PropTypes.object,
intl: PropTypes.object.isRequired,
onTitleChange: PropTypes.func.isRequired,
onDescriptionChange: PropTypes.func.isRequired,
onChangeGroupId: PropTypes.func.isRequired,
onChangeGroupTags: PropTypes.func.isRequired,
onChangeGroupCategory: PropTypes.func.isRequired,
onChangeGroupIsPrivate: PropTypes.func.isRequired,
onChangeGroupIsVisible: PropTypes.func.isRequired,
onFetchGroup: PropTypes.func.isRequired,
onFetchGroupCategories: PropTypes.func.isRequired,
onResetEditor: PropTypes.func.isRequired,
onSetGroup: PropTypes.func.isRequired,
onSubmit: PropTypes.func.isRequired,
isSubmitting: PropTypes.bool,
isAdmin: PropTypes.bool,
onClose: PropTypes.func,
idValue: PropTypes.string.isRequired,
tags: PropTypes.string.isRequired,
category: PropTypes.string.isRequired,
isPrivate: PropTypes.bool.isRequired,
isVisible: PropTypes.bool.isRequired,
categories: ImmutablePropTypes.list.isRequired,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(GroupCreate))

View File

@ -19,50 +19,8 @@ import BlockHeading from '../components/block_heading'
import Input from '../components/input'
import ScrollableList from '../components/scrollable_list'
const mapStateToProps = (state, { params }) => {
const groupId = isObject(params) ? params['id'] : -1
const group = groupId === -1 ? null : state.getIn(['groups', groupId])
return {
group,
groupId,
relationships: state.getIn(['group_relationships', groupId]),
accountIds: state.getIn(['user_lists', 'groups', groupId, 'items']),
hasMore: !!state.getIn(['user_lists', 'groups', groupId, 'next']),
}
}
const mapDispatchToProps = (dispatch) => ({
onFetchMembers(groupId) {
dispatch(fetchMembers(groupId))
},
onExpandMembers(groupId) {
dispatch(expandMembers(groupId))
},
onOpenGroupMemberOptions(targetRef, accountId, groupId) {
dispatch(openPopover('GROUP_MEMBER_OPTIONS', {
targetRef,
accountId,
groupId,
position: 'top',
}))
},
})
export default
@connect(mapStateToProps, mapDispatchToProps)
class GroupMembers extends ImmutablePureComponent {
static propTypes = {
group: ImmutablePropTypes.map,
groupId: PropTypes.string.isRequired,
accountIds: ImmutablePropTypes.list,
hasMore: PropTypes.bool,
onExpandMembers: PropTypes.func.isRequired,
onFetchMembers: PropTypes.func.isRequired,
onOpenGroupMemberOptions: PropTypes.func.isRequired,
}
componentWillMount() {
const { groupId } = this.props
@ -146,3 +104,45 @@ class GroupMembers extends ImmutablePureComponent {
}
}
const mapStateToProps = (state, { params }) => {
const groupId = isObject(params) ? params['id'] : -1
const group = groupId === -1 ? null : state.getIn(['groups', groupId])
return {
group,
groupId,
relationships: state.getIn(['group_relationships', groupId]),
accountIds: state.getIn(['user_lists', 'groups', groupId, 'items']),
hasMore: !!state.getIn(['user_lists', 'groups', groupId, 'next']),
}
}
const mapDispatchToProps = (dispatch) => ({
onFetchMembers(groupId) {
dispatch(fetchMembers(groupId))
},
onExpandMembers(groupId) {
dispatch(expandMembers(groupId))
},
onOpenGroupMemberOptions(targetRef, accountId, groupId) {
dispatch(openPopover('GROUP_MEMBER_OPTIONS', {
targetRef,
accountId,
groupId,
position: 'top',
}))
},
})
GroupMembers.propTypes = {
group: ImmutablePropTypes.map,
groupId: PropTypes.string.isRequired,
accountIds: ImmutablePropTypes.list,
hasMore: PropTypes.bool,
onExpandMembers: PropTypes.func.isRequired,
onFetchMembers: PropTypes.func.isRequired,
onOpenGroupMemberOptions: PropTypes.func.isRequired,
}
export default connect(mapStateToProps, mapDispatchToProps)(GroupMembers)

View File

@ -18,48 +18,8 @@ import BlockHeading from '../components/block_heading'
import ColumnIndicator from '../components/column_indicator'
import ScrollableList from '../components/scrollable_list'
const messages = defineMessages({
remove: { id: 'groups.removed_accounts', defaultMessage: 'Allow joining' },
})
const mapStateToProps = (state, { params }) => {
const groupId = isObject(params) ? params['id'] : -1
const group = groupId === -1 ? null : state.getIn(['groups', groupId])
return {
group,
groupId,
accountIds: state.getIn(['user_lists', 'groups_removed_accounts', groupId, 'items']),
hasMore: !!state.getIn(['user_lists', 'groups_removed_accounts', groupId, 'next']),
}
}
const mapDispatchToProps = (dispatch) => ({
onFetchRemovedAccounts(groupId) {
dispatch(fetchRemovedAccounts(groupId))
},
onExpandRemovedAccounts(groupId) {
dispatch(expandRemovedAccounts(groupId))
},
onRemoveRemovedAccount(groupId, accountId) {
dispatch(removeRemovedAccount(groupId, accountId))
},
})
export default
@injectIntl
@connect(mapStateToProps, mapDispatchToProps)
class GroupRemovedAccounts extends ImmutablePureComponent {
static propTypes = {
groupId: PropTypes.string.isRequired,
accountIds: ImmutablePropTypes.list,
hasMore: PropTypes.bool,
onFetchRemovedAccounts: PropTypes.func.isRequired,
onExpandRemovedAccounts: PropTypes.func.isRequired,
onRemoveRemovedAccount: PropTypes.func.isRequired,
}
componentWillMount() {
const { groupId } = this.props
@ -113,3 +73,42 @@ class GroupRemovedAccounts extends ImmutablePureComponent {
}
}
const messages = defineMessages({
remove: { id: 'groups.removed_accounts', defaultMessage: 'Allow joining' },
})
const mapStateToProps = (state, { params }) => {
const groupId = isObject(params) ? params['id'] : -1
const group = groupId === -1 ? null : state.getIn(['groups', groupId])
return {
group,
groupId,
accountIds: state.getIn(['user_lists', 'groups_removed_accounts', groupId, 'items']),
hasMore: !!state.getIn(['user_lists', 'groups_removed_accounts', groupId, 'next']),
}
}
const mapDispatchToProps = (dispatch) => ({
onFetchRemovedAccounts(groupId) {
dispatch(fetchRemovedAccounts(groupId))
},
onExpandRemovedAccounts(groupId) {
dispatch(expandRemovedAccounts(groupId))
},
onRemoveRemovedAccount(groupId, accountId) {
dispatch(removeRemovedAccount(groupId, accountId))
},
})
GroupRemovedAccounts.propTypes = {
groupId: PropTypes.string.isRequired,
accountIds: ImmutablePropTypes.list,
hasMore: PropTypes.bool,
onFetchRemovedAccounts: PropTypes.func.isRequired,
onExpandRemovedAccounts: PropTypes.func.isRequired,
onRemoveRemovedAccount: PropTypes.func.isRequired,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(GroupRemovedAccounts))

View File

@ -21,54 +21,8 @@ import StatusList from '../components/status_list'
import ColumnIndicator from '../components/column_indicator'
import GroupSortBlock from '../components/group_sort_block'
const messages = defineMessages({
empty: { id: 'empty_column.group', defaultMessage: 'There is nothing in this group yet.\nWhen members of this group post new statuses, they will appear here.' },
})
const mapStateToProps = (state, props) => ({
groupId: props.params.id,
group: state.getIn(['groups', props.params.id]),
sortByValue: state.getIn(['group_lists', 'sortByValue']),
sortByTopValue: state.getIn(['group_lists', 'sortByTopValue']),
})
const mapDispatchToProps = (dispatch) => ({
onConnectGroupStream(groupId) {
dispatch(connectGroupStream(groupId))
},
onClearTimeline(timelineId) {
dispatch(clearTimeline(timelineId))
},
onExpandGroupTimeline(groupId, options) {
dispatch(expandGroupTimeline(groupId, options))
},
setMemberNewest() {
dispatch(setGroupTimelineSort(GROUP_TIMELINE_SORTING_TYPE_NEWEST))
},
})
export default
@connect(mapStateToProps, mapDispatchToProps)
@injectIntl
class GroupTimeline extends ImmutablePureComponent {
static propTypes = {
params: PropTypes.object.isRequired,
group: PropTypes.oneOfType([
ImmutablePropTypes.map,
PropTypes.bool,
]),
groupId: PropTypes.string,
intl: PropTypes.object.isRequired,
onConnectGroupStream: PropTypes.func.isRequired,
onClearTimeline: PropTypes.func.isRequired,
onExpandGroupTimeline: PropTypes.func.isRequired,
setMemberNewest: PropTypes.func.isRequired,
sortByValue: PropTypes.string.isRequired,
sortByTopValue: PropTypes.string,
onlyMedia: PropTypes.bool,
}
state = {
//keep track of loads for if no user,
//only allow 2 loads before showing sign up msg
@ -151,3 +105,48 @@ class GroupTimeline extends ImmutablePureComponent {
}
}
const messages = defineMessages({
empty: { id: 'empty_column.group', defaultMessage: 'There is nothing in this group yet.\nWhen members of this group post new statuses, they will appear here.' },
})
const mapStateToProps = (state, props) => ({
groupId: props.params.id,
group: state.getIn(['groups', props.params.id]),
sortByValue: state.getIn(['group_lists', 'sortByValue']),
sortByTopValue: state.getIn(['group_lists', 'sortByTopValue']),
})
const mapDispatchToProps = (dispatch) => ({
onConnectGroupStream(groupId) {
dispatch(connectGroupStream(groupId))
},
onClearTimeline(timelineId) {
dispatch(clearTimeline(timelineId))
},
onExpandGroupTimeline(groupId, options) {
dispatch(expandGroupTimeline(groupId, options))
},
setMemberNewest() {
dispatch(setGroupTimelineSort(GROUP_TIMELINE_SORTING_TYPE_NEWEST))
},
})
GroupTimeline.propTypes = {
params: PropTypes.object.isRequired,
group: PropTypes.oneOfType([
ImmutablePropTypes.map,
PropTypes.bool,
]),
groupId: PropTypes.string,
intl: PropTypes.object.isRequired,
onConnectGroupStream: PropTypes.func.isRequired,
onClearTimeline: PropTypes.func.isRequired,
onExpandGroupTimeline: PropTypes.func.isRequired,
setMemberNewest: PropTypes.func.isRequired,
sortByValue: PropTypes.string.isRequired,
sortByTopValue: PropTypes.string,
onlyMedia: PropTypes.bool,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(GroupTimeline))

View File

@ -13,46 +13,8 @@ import ColumnIndicator from '../components/column_indicator'
import Heading from '../components/heading'
import GroupListItem from '../components/group_list_item'
const messages = defineMessages({
empty: { id: 'groups.empty', defaultMessage: 'There are no groups to display' },
featured: { id: 'featured', defaultMessage: 'Featured' },
new: { id: 'new', defaultMessage: 'Just Added' },
member: { id: 'my_groups', defaultMessage: 'My Groups' },
admin: { id: 'admin', defaultMessage: 'Admin' },
})
const mapStateToProps = (state, { activeTab }) => ({
groupIds: state.getIn(['group_lists', activeTab, 'items']),
isFetched: state.getIn(['group_lists', activeTab, 'isFetched']),
isLoading: state.getIn(['group_lists', activeTab, 'isLoading']),
})
const mapDispatchToProps = (dispatch) => ({
onFetchGroups: (tab) => dispatch(fetchGroups(tab)),
onOpenSortPopover(tab, targetRef) {
dispatch(openPopover(POPOVER_GROUP_LIST_SORT_OPTIONS, {
targetRef,
tab,
position: 'bottom',
}))
}
})
export default
@injectIntl
@connect(mapStateToProps, mapDispatchToProps)
class GroupsCollection extends ImmutablePureComponent {
static propTypes = {
activeTab: PropTypes.string.isRequired,
groupIds: ImmutablePropTypes.list,
intl: PropTypes.object.isRequired,
isFetched: PropTypes.bool.isRequired,
isLoading: PropTypes.bool.isRequired,
onFetchGroups: PropTypes.func.isRequired,
onOpenSortPopover: PropTypes.func.isRequired,
}
componentWillMount() {
this.props.onFetchGroups(this.props.activeTab)
}
@ -124,4 +86,41 @@ class GroupsCollection extends ImmutablePureComponent {
)
}
}
}
const messages = defineMessages({
empty: { id: 'groups.empty', defaultMessage: 'There are no groups to display' },
featured: { id: 'featured', defaultMessage: 'Featured' },
new: { id: 'new', defaultMessage: 'Just Added' },
member: { id: 'my_groups', defaultMessage: 'My Groups' },
admin: { id: 'admin', defaultMessage: 'Admin' },
})
const mapStateToProps = (state, { activeTab }) => ({
groupIds: state.getIn(['group_lists', activeTab, 'items']),
isFetched: state.getIn(['group_lists', activeTab, 'isFetched']),
isLoading: state.getIn(['group_lists', activeTab, 'isLoading']),
})
const mapDispatchToProps = (dispatch) => ({
onFetchGroups: (tab) => dispatch(fetchGroups(tab)),
onOpenSortPopover(tab, targetRef) {
dispatch(openPopover(POPOVER_GROUP_LIST_SORT_OPTIONS, {
targetRef,
tab,
position: 'bottom',
}))
}
})
GroupsCollection.propTypes = {
activeTab: PropTypes.string.isRequired,
groupIds: ImmutablePropTypes.list,
intl: PropTypes.object.isRequired,
isFetched: PropTypes.bool.isRequired,
isLoading: PropTypes.bool.isRequired,
onFetchGroups: PropTypes.func.isRequired,
onOpenSortPopover: PropTypes.func.isRequired,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(GroupsCollection))

View File

@ -7,22 +7,10 @@ import { expandHashtagTimeline, clearTimeline } from '../actions/timelines'
import { connectHashtagStream } from '../actions/streaming'
import StatusList from '../components/status_list'
const mapStateToProps = (state, props) => ({
hasUnread: state.getIn(['timelines', `hashtag:${props.params.id}`, 'unread']) > 0,
})
export default
@connect(mapStateToProps)
class HashtagTimeline extends React.PureComponent {
disconnects = [];
static propTypes = {
params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
hasUnread: PropTypes.bool,
}
title = () => {
const title = [this.props.params.id]
@ -141,3 +129,15 @@ class HashtagTimeline extends React.PureComponent {
}
}
const mapStateToProps = (state, props) => ({
hasUnread: state.getIn(['timelines', `hashtag:${props.params.id}`, 'unread']) > 0,
})
HashtagTimeline.propTypes = {
params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
hasUnread: PropTypes.bool,
}
export default connect(mapStateToProps)(HashtagTimeline)

View File

@ -10,34 +10,8 @@ import {
} from '../actions/timelines'
import StatusList from '../components/status_list'
const messages = defineMessages({
title: { id: 'column.home', defaultMessage: 'Home' },
empty: { id: 'empty_timeline.home', defaultMessage: 'Your home timeline is empty. Start following other users to receive their content here.' },
})
const mapStateToProps = (state) => ({
isPartial: state.getIn(['timelines', 'home', 'isPartial']),
})
const mapDispatchToProps = (dispatch) => ({
onExpandHomeTimeline(options) {
if (!options) dispatch(forceDequeueTimeline('home'))
dispatch(expandHomeTimeline(options))
},
})
export default
@injectIntl
@withRouter
@connect(mapStateToProps, mapDispatchToProps)
class HomeTimeline extends React.PureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
isPartial: PropTypes.bool,
onExpandHomeTimeline: PropTypes.func.isRequired,
}
componentDidMount () {
this._checkIfReloadNeeded(false, this.props.isPartial)
}
@ -99,4 +73,28 @@ class HomeTimeline extends React.PureComponent {
)
}
}
}
const messages = defineMessages({
title: { id: 'column.home', defaultMessage: 'Home' },
empty: { id: 'empty_timeline.home', defaultMessage: 'Your home timeline is empty. Start following other users to receive their content here.' },
})
const mapStateToProps = (state) => ({
isPartial: state.getIn(['timelines', 'home', 'isPartial']),
})
const mapDispatchToProps = (dispatch) => ({
onExpandHomeTimeline(options) {
if (!options) dispatch(forceDequeueTimeline('home'))
dispatch(expandHomeTimeline(options))
},
})
HomeTimeline.propTypes = {
intl: PropTypes.object.isRequired,
isPartial: PropTypes.bool,
onExpandHomeTimeline: PropTypes.func.isRequired,
}
export default injectIntl(withRouter(connect(mapStateToProps, mapDispatchToProps)(HomeTimeline)))

View File

@ -27,39 +27,29 @@ import Pagination from '../components/pagination'
import ComposeFormContainer from './compose/containers/compose_form_container'
import Responsive from './ui/util/responsive_component'
class SlideWelcome extends React.PureComponent {
const SlideWelcome = () => (
<div className={[_s.d, _s.w100PC, _s.h100PC].join(' ')}>
<Image src='/headers/onboarding.png' alt='Welcome to Gab' />
render() {
return (
<div className={[_s.d, _s.w100PC, _s.h100PC].join(' ')}>
<Image src='/headers/onboarding.png' alt='Welcome to Gab' />
<div className={[_s.d, _s.px15, _s.py15].join(' ')}>
<div className={[_s.d, _s.px15, _s.py15].join(' ')}>
<Text size='large'>Gab is the home of free speech online and a place where users shape their own experience. </Text>
<br />
<Text size='large'>You will discover many different ideas, people, and topics on Gab.</Text>
<br />
<Text size='large'>Follow the people you find interesting and block or mute people you don't want to associate with.</Text>
<br />
<Text size='large'>Speak freely, associate freely!</Text>
<br />
<Text size='large'>Let's get started!</Text>
<Text size='large'>Gab is the home of free speech online and a place where users shape their own experience. </Text>
<br />
<Text size='large'>You will discover many different ideas, people, and topics on Gab.</Text>
<br />
<Text size='large'>Follow the people you find interesting and block or mute people you don't want to associate with.</Text>
<br />
<Text size='large'>Speak freely, associate freely!</Text>
<br />
<Text size='large'>Let's get started!</Text>
</div>
</div>
</div>
)
}
}
</div>
)
class SlidePhotos extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map.isRequired,
}
state = {
displayNameValue: this.props.account.get('display_name'),
}
@ -138,11 +128,11 @@ class SlidePhotos extends ImmutablePureComponent {
}
class SlideGroups extends ImmutablePureComponent {
SlidePhotos.propTypes = {
account: ImmutablePropTypes.map.isRequired,
}
static propTypes = {
groupIds: ImmutablePropTypes.list,
}
class SlideGroups extends ImmutablePureComponent {
render() {
const { groupIds } = this.props
@ -174,12 +164,11 @@ class SlideGroups extends ImmutablePureComponent {
}
class SlideFirstPost extends React.PureComponent {
SlideGroups.propTypes = {
groupIds: ImmutablePropTypes.list,
}
static propTypes = {
submitted: PropTypes.bool.isRequired,
onNext: PropTypes.func.isRequired,
}
class SlideFirstPost extends React.PureComponent {
render() {
const { submitted } = this.props
@ -228,35 +217,13 @@ class SlideFirstPost extends React.PureComponent {
}
const mapStateToProps = (state) => ({
account: makeGetAccount()(state, me),
groupIds: state.getIn(['group_lists', 'featured', 'items']),
shownOnboarding: state.getIn(['settings', 'shownOnboarding'], false),
isSubmitting: state.getIn(['compose', 'is_submitting']),
})
SlideFirstPost.propTypes = {
submitted: PropTypes.bool.isRequired,
onNext: PropTypes.func.isRequired,
}
const mapDispatchToProps = (dispatch) => ({
onSaveShownOnboarding: () => dispatch(saveShownOnboarding()),
onFetchFeaturedGroups: () => dispatch(fetchGroups('featured')),
onSaveUserProfileInformation(data) {
dispatch(saveUserProfileInformation(data))
},
})
export default
@connect(mapStateToProps, mapDispatchToProps)
class Introduction extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map.isRequired,
groupIds: ImmutablePropTypes.list,
isSubmitting: PropTypes.bool.isRequired,
shownOnboarding: PropTypes.bool.isRequired,
onSaveShownOnboarding: PropTypes.func.isRequired,
onFetchFeaturedGroups: PropTypes.func.isRequired,
onSaveUserProfileInformation: PropTypes.func.isRequired,
}
state = {
currentIndex: 0,
submittedFirstPost: false,
@ -436,4 +403,31 @@ class Introduction extends ImmutablePureComponent {
)
}
}
}
const mapStateToProps = (state) => ({
account: makeGetAccount()(state, me),
groupIds: state.getIn(['group_lists', 'featured', 'items']),
shownOnboarding: state.getIn(['settings', 'shownOnboarding'], false),
isSubmitting: state.getIn(['compose', 'is_submitting']),
})
const mapDispatchToProps = (dispatch) => ({
onSaveShownOnboarding: () => dispatch(saveShownOnboarding()),
onFetchFeaturedGroups: () => dispatch(fetchGroups('featured')),
onSaveUserProfileInformation(data) {
dispatch(saveUserProfileInformation(data))
},
})
Introduction.propTypes = {
account: ImmutablePropTypes.map.isRequired,
groupIds: ImmutablePropTypes.list,
isSubmitting: PropTypes.bool.isRequired,
shownOnboarding: PropTypes.bool.isRequired,
onSaveShownOnboarding: PropTypes.func.isRequired,
onFetchFeaturedGroups: PropTypes.func.isRequired,
onSaveUserProfileInformation: PropTypes.func.isRequired,
}
export default connect(mapStateToProps, mapDispatchToProps)(Introduction)

View File

@ -10,27 +10,8 @@ import { meUsername } from '../initial_state'
import StatusList from '../components/status_list'
import ColumnIndicator from '../components/column_indicator'
const mapStateToProps = (state, { params: { username } }) => {
return {
isMyAccount: (username.toLowerCase() === meUsername.toLowerCase()),
statusIds: state.getIn(['status_lists', 'favorites', 'items']),
isLoading: state.getIn(['status_lists', 'favorites', 'isLoading'], true),
hasMore: !!state.getIn(['status_lists', 'favorites', 'next']),
}
}
export default
@connect(mapStateToProps)
class LikedStatuses extends ImmutablePureComponent {
static propTypes = {
dispatch: PropTypes.func.isRequired,
statusIds: ImmutablePropTypes.list.isRequired,
hasMore: PropTypes.bool,
isLoading: PropTypes.bool,
isMyAccount: PropTypes.bool.isRequired,
}
componentWillMount() {
this.props.dispatch(fetchFavoritedStatuses())
}
@ -64,3 +45,20 @@ class LikedStatuses extends ImmutablePureComponent {
}
}
const mapStateToProps = (state, { params: { username } }) => ({
isMyAccount: (username.toLowerCase() === meUsername.toLowerCase()),
statusIds: state.getIn(['status_lists', 'favorites', 'items']),
isLoading: state.getIn(['status_lists', 'favorites', 'isLoading'], true),
hasMore: !!state.getIn(['status_lists', 'favorites', 'next']),
})
LikedStatuses.propTypes = {
dispatch: PropTypes.func.isRequired,
statusIds: ImmutablePropTypes.list.isRequired,
hasMore: PropTypes.bool,
isLoading: PropTypes.bool,
isMyAccount: PropTypes.bool.isRequired,
}
export default connect(mapStateToProps)(LikedStatuses)

View File

@ -10,39 +10,8 @@ import Input from '../components/input'
import Form from '../components/form'
import Text from '../components/text'
const messages = defineMessages({
label: { id: 'lists.new.title_placeholder', defaultMessage: 'New list title' },
create: { id: 'lists.new.create_title', defaultMessage: 'Create list' },
list_description: { id: 'list.description', defaultMessage: 'Lists are private and only you can see who is on a list.\nNo one else can view your lists. No one knows that they are on your list.' },
new_list_placeholder: { id: 'list.title_placeholder', defaultMessage: 'My new list...', },
})
const mapStateToProps = (state) => ({
value: state.getIn(['listEditor', 'title']),
disabled: state.getIn(['listEditor', 'isSubmitting']),
})
const mapDispatchToProps = (dispatch, { isModal }) => ({
onChange: (value) => dispatch(changeListEditorTitle(value)),
onSubmit: () => {
if (isModal) dispatch(closeModal(MODAL_LIST_CREATE))
dispatch(submitListEditor(true))
},
})
export default
@connect(mapStateToProps, mapDispatchToProps)
@injectIntl
class ListCreate extends React.PureComponent {
static propTypes = {
value: PropTypes.string,
intl: PropTypes.object.isRequired,
onChange: PropTypes.func.isRequired,
onSubmit: PropTypes.func.isRequired,
isModal: PropTypes.bool,
}
render() {
const {
value,
@ -81,3 +50,33 @@ class ListCreate extends React.PureComponent {
}
}
const messages = defineMessages({
label: { id: 'lists.new.title_placeholder', defaultMessage: 'New list title' },
create: { id: 'lists.new.create_title', defaultMessage: 'Create list' },
list_description: { id: 'list.description', defaultMessage: 'Lists are private and only you can see who is on a list.\nNo one else can view your lists. No one knows that they are on your list.' },
new_list_placeholder: { id: 'list.title_placeholder', defaultMessage: 'My new list...', },
})
const mapStateToProps = (state) => ({
value: state.getIn(['listEditor', 'title']),
disabled: state.getIn(['listEditor', 'isSubmitting']),
})
const mapDispatchToProps = (dispatch, { isModal }) => ({
onChange: (value) => dispatch(changeListEditorTitle(value)),
onSubmit: () => {
if (isModal) dispatch(closeModal(MODAL_LIST_CREATE))
dispatch(submitListEditor(true))
},
})
ListCreate.propTypes = {
value: PropTypes.string,
intl: PropTypes.object.isRequired,
onChange: PropTypes.func.isRequired,
onSubmit: PropTypes.func.isRequired,
isModal: PropTypes.bool,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(ListCreate))

View File

@ -26,104 +26,8 @@ import Input from '../components/input'
import TabBar from '../components/tab_bar'
import Text from '../components/text'
const messages = defineMessages({
close: { id: 'lightbox.close', defaultMessage: 'Close' },
save: { id: 'lists.new.save_title', defaultMessage: 'Save Title' },
changeTitle: { id: 'lists.edit.submit', defaultMessage: 'Change title' },
addToList: { id: 'lists.account.add', defaultMessage: 'Add to list' },
removeFromList: { id: 'lists.account.remove', defaultMessage: 'Remove from list' },
editList: { id: 'lists.edit', defaultMessage: 'Edit list' },
editListTitle: { id: 'lists.new.edit_title_placeholder', defaultMessage: 'Edit list title' },
remove: { id: 'lists.account.remove', defaultMessage: 'Remove from list' },
add: { id: 'lists.account.add', defaultMessage: 'Add to list' },
search: { id: 'lists.search', defaultMessage: 'Search people...' },
searchMembers: { id: 'lists.search_members', defaultMessage: 'Search members...' },
searchTitle: { id: 'tabs_bar.search', defaultMessage: 'Search' },
})
const mapStateToProps = (state, { params, id }) => {
const listId = isObject(params) ? params['id'] : id
return {
listId,
list: state.getIn(['lists', listId]),
title: state.getIn(['listEditor', 'title']),
disabled: !state.getIn(['listEditor', 'isChanged']),
accountIds: state.getIn(['listEditor', 'accounts', 'items']),
searchAccountIds: state.getIn(['listEditor', 'suggestions', 'items']),
searchSuggestionsValue: state.getIn(['listEditor', 'suggestions', 'value']),
}
}
const mapDispatchToProps = (dispatch) => ({
onDeleteList(list) {
dispatch(openModal(MODAL_LIST_DELETE, { list }))
},
onChangeTitle(value) {
dispatch(changeListEditorTitle(value))
},
onUpdateList() {
dispatch(submitListEditor(false))
},
onInitialize(listId) {
dispatch(setupListEditor(listId))
},
onReset() {
dispatch(resetListEditor())
},
onRemoveAccountFromList(accountId) {
dispatch(removeFromListEditor(accountId))
},
onAddAccountToList(accountId) {
dispatch(addToListEditor(accountId))
},
onSubmitSearchSuggestions(value) {
dispatch(fetchListSuggestions(value))
},
onClearSearchSuggestions() {
dispatch(clearListSuggestions())
},
onChangeSuggestions(value) {
dispatch(changeListSuggestions(value))
},
})
export default
@connect(mapStateToProps, mapDispatchToProps)
@injectIntl
class ListEdit extends ImmutablePureComponent {
static propTypes = {
list: ImmutablePropTypes.map,
title: PropTypes.string,
listId: PropTypes.string.isRequired,
onClose: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
onInitialize: PropTypes.func.isRequired,
onReset: PropTypes.func.isRequired,
searchSuggestionsValue: PropTypes.string.isRequired,
accountIds: ImmutablePropTypes.list.isRequired,
searchAccountIds: ImmutablePropTypes.list.isRequired,
onRemoveAccountFromList: PropTypes.func.isRequired,
onAddAccountToList: PropTypes.func.isRequired,
onChangeSuggestions: PropTypes.func.isRequired,
onClearSearchSuggestions: PropTypes.func.isRequired,
onSubmitSearchSuggestions: PropTypes.func.isRequired,
onDeleteList: PropTypes.func.isRequired,
tab: PropTypes.string,
}
state = {
activeTab: this.props.tab || 'members'
}
@ -317,3 +221,98 @@ class ListEdit extends ImmutablePureComponent {
}
}
const messages = defineMessages({
close: { id: 'lightbox.close', defaultMessage: 'Close' },
save: { id: 'lists.new.save_title', defaultMessage: 'Save Title' },
changeTitle: { id: 'lists.edit.submit', defaultMessage: 'Change title' },
addToList: { id: 'lists.account.add', defaultMessage: 'Add to list' },
removeFromList: { id: 'lists.account.remove', defaultMessage: 'Remove from list' },
editList: { id: 'lists.edit', defaultMessage: 'Edit list' },
editListTitle: { id: 'lists.new.edit_title_placeholder', defaultMessage: 'Edit list title' },
remove: { id: 'lists.account.remove', defaultMessage: 'Remove from list' },
add: { id: 'lists.account.add', defaultMessage: 'Add to list' },
search: { id: 'lists.search', defaultMessage: 'Search people...' },
searchMembers: { id: 'lists.search_members', defaultMessage: 'Search members...' },
searchTitle: { id: 'tabs_bar.search', defaultMessage: 'Search' },
})
const mapStateToProps = (state, { params, id }) => {
const listId = isObject(params) ? params['id'] : id
return {
listId,
list: state.getIn(['lists', listId]),
title: state.getIn(['listEditor', 'title']),
disabled: !state.getIn(['listEditor', 'isChanged']),
accountIds: state.getIn(['listEditor', 'accounts', 'items']),
searchAccountIds: state.getIn(['listEditor', 'suggestions', 'items']),
searchSuggestionsValue: state.getIn(['listEditor', 'suggestions', 'value']),
}
}
const mapDispatchToProps = (dispatch) => ({
onDeleteList(list) {
dispatch(openModal(MODAL_LIST_DELETE, { list }))
},
onChangeTitle(value) {
dispatch(changeListEditorTitle(value))
},
onUpdateList() {
dispatch(submitListEditor(false))
},
onInitialize(listId) {
dispatch(setupListEditor(listId))
},
onReset() {
dispatch(resetListEditor())
},
onRemoveAccountFromList(accountId) {
dispatch(removeFromListEditor(accountId))
},
onAddAccountToList(accountId) {
dispatch(addToListEditor(accountId))
},
onSubmitSearchSuggestions(value) {
dispatch(fetchListSuggestions(value))
},
onClearSearchSuggestions() {
dispatch(clearListSuggestions())
},
onChangeSuggestions(value) {
dispatch(changeListSuggestions(value))
},
})
ListEdit.propTypes = {
list: ImmutablePropTypes.map,
title: PropTypes.string,
listId: PropTypes.string.isRequired,
onClose: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
onInitialize: PropTypes.func.isRequired,
onReset: PropTypes.func.isRequired,
searchSuggestionsValue: PropTypes.string.isRequired,
accountIds: ImmutablePropTypes.list.isRequired,
searchAccountIds: ImmutablePropTypes.list.isRequired,
onRemoveAccountFromList: PropTypes.func.isRequired,
onAddAccountToList: PropTypes.func.isRequired,
onChangeSuggestions: PropTypes.func.isRequired,
onClearSearchSuggestions: PropTypes.func.isRequired,
onSubmitSearchSuggestions: PropTypes.func.isRequired,
onDeleteList: PropTypes.func.isRequired,
tab: PropTypes.string,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(ListEdit))

View File

@ -12,28 +12,11 @@ import StatusList from '../components/status_list'
import ColumnIndicator from '../components/column_indicator'
import Button from '../components/button'
import Text from '../components/text'
import Block from '../components/block'
const mapStateToProps = (state, props) => ({
list: state.getIn(['lists', props.params.id]),
})
export default
@connect(mapStateToProps)
class ListTimeline extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = {
params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
list: PropTypes.oneOfType([
ImmutablePropTypes.map,
PropTypes.bool,
]),
intl: PropTypes.object.isRequired,
}
componentDidMount() {
@ -118,3 +101,19 @@ class ListTimeline extends ImmutablePureComponent {
}
}
const mapStateToProps = (state, props) => ({
list: state.getIn(['lists', props.params.id]),
})
ListTimeline.propTypes = {
params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
list: PropTypes.oneOfType([
ImmutablePropTypes.map,
PropTypes.bool,
]),
intl: PropTypes.object.isRequired,
}
export default connect(mapStateToProps)(ListTimeline)

View File

@ -6,33 +6,10 @@ import ImmutablePropTypes from 'react-immutable-proptypes'
import { defineMessages, injectIntl } from 'react-intl'
import { getOrderedLists } from '../selectors'
import { fetchLists } from '../actions/lists'
import ColumnIndicator from '../components/column_indicator'
import List from '../components/list'
const messages = defineMessages({
add: { id: 'lists.new.create', defaultMessage: 'Add List' },
empty: { id: 'empty_column.lists', defaultMessage: 'You don\'t have any lists yet. When you create one, it will show up here.' },
})
const mapStateToProps = (state) => ({
lists: getOrderedLists(state),
})
const mapDispatchToProps = (dispatch) => ({
onFetchLists: () => dispatch(fetchLists()),
})
export default
@connect(mapStateToProps, mapDispatchToProps)
@injectIntl
class ListsDirectory extends ImmutablePureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
lists: ImmutablePropTypes.list,
onFetchLists: PropTypes.func.isRequired,
}
state = {
fetched: false,
}
@ -64,4 +41,25 @@ class ListsDirectory extends ImmutablePureComponent {
)
}
}
}
const messages = defineMessages({
add: { id: 'lists.new.create', defaultMessage: 'Add List' },
empty: { id: 'empty_column.lists', defaultMessage: 'You don\'t have any lists yet. When you create one, it will show up here.' },
})
const mapStateToProps = (state) => ({
lists: getOrderedLists(state),
})
const mapDispatchToProps = (dispatch) => ({
onFetchLists: () => dispatch(fetchLists()),
})
ListsDirectory.propTypes = {
intl: PropTypes.object.isRequired,
lists: ImmutablePropTypes.list,
onFetchLists: PropTypes.func.isRequired,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(ListsDirectory))

View File

@ -12,30 +12,8 @@ import Block from '../components/block'
import BlockHeading from '../components/block_heading'
import ScrollableList from '../components/scrollable_list'
const mapStateToProps = (state) => ({
accountIds: state.getIn(['user_lists', 'mutes', me, 'items']),
hasMore: !!state.getIn(['user_lists', 'mutes', me, 'next']),
isLoading: state.getIn(['user_lists', 'mutes', me, 'isLoading']),
})
const mapDispatchToProps = (dispatch) => ({
onFetchMutes: () => dispatch(fetchMutes()),
onExpandMutes: () => dispatch(expandMutes()),
})
export default
@connect(mapStateToProps, mapDispatchToProps)
@injectIntl
class Mutes extends ImmutablePureComponent {
static propTypes = {
accountIds: ImmutablePropTypes.list,
hasMore: PropTypes.bool,
isLoading: PropTypes.bool,
onExpandMutes: PropTypes.func.isRequired,
onFetchMutes: PropTypes.func.isRequired,
}
componentWillMount() {
this.props.onFetchMutes()
}
@ -76,3 +54,24 @@ class Mutes extends ImmutablePureComponent {
}
}
const mapStateToProps = (state) => ({
accountIds: state.getIn(['user_lists', 'mutes', me, 'items']),
hasMore: !!state.getIn(['user_lists', 'mutes', me, 'next']),
isLoading: state.getIn(['user_lists', 'mutes', me, 'isLoading']),
})
const mapDispatchToProps = (dispatch) => ({
onFetchMutes: () => dispatch(fetchMutes()),
onExpandMutes: () => dispatch(expandMutes()),
})
Mutes.propTypes = {
accountIds: ImmutablePropTypes.list,
hasMore: PropTypes.bool,
isLoading: PropTypes.bool,
onExpandMutes: PropTypes.func.isRequired,
onFetchMutes: PropTypes.func.isRequired,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(Mutes))

View File

@ -17,37 +17,12 @@ import TabBar from '../components/tab_bar'
import Text from '../components/text'
import TrendsItem from '../components/trends_item'
// const messages = defineMessages({
// title: { id: 'trends.title', defaultMessage: 'Trending right now' },
// })
const mapStateToProps = (state) => ({
isError: state.getIn(['gab_trends', 'partner', 'isError']),
isLoading: state.getIn(['gab_trends', 'partner', 'isLoading']),
items: state.getIn(['gab_trends', 'partner', 'items']),
})
const mapDispatchToProps = (dispatch) => ({
onfetchGabTrends: () => dispatch(fetchGabTrends('partner')),
})
export default
@withRouter
@connect(mapStateToProps, mapDispatchToProps)
class News extends React.PureComponent {
static contextTypes = {
router: PropTypes.object.isRequired,
}
static propTypes = {
intl: PropTypes.object.isRequired,
isError: PropTypes.bool,
isLoading: PropTypes.bool,
items: PropTypes.object,
onfetchGabTrends: PropTypes.func.isRequired,
}
state = {
activeDomain: null,
}
@ -75,7 +50,7 @@ class News extends React.PureComponent {
}
}
render () {
render() {
const {
intl,
isError,
@ -102,7 +77,7 @@ class News extends React.PureComponent {
if (activeDomain) {
const domainBlock = items.trackedDomains.find((d) => `${d.domain}`.toLowerCase() === activeDomain)
if (domainBlock) domainExists = true
todaysTop = domainBlock.topUrls
todaysTopTitle = domainBlock.title
} else {
@ -114,14 +89,14 @@ class News extends React.PureComponent {
domainTabs = domains.map((block) => ({
title: block.title,
to: `/news?domain=${block.domain}`,
onClick: () => {},
onClick: () => { },
active: activeDomain === `${block.domain}`.toLowerCase(),
}))
domainTabs = [
{
title: "Today's Top",
to: `/news`,
onClick: () => {},
onClick: () => { },
active: !activeDomain,
},
...domainTabs,
@ -165,32 +140,32 @@ class News extends React.PureComponent {
</Heading>
</div>
}
{
!activeDomain && leadHeadlines.length > 0 &&
<div className={[_s.d, _s.mb15].join(' ')}>
<div className={[_s.d, _s.px15, _s.py10, _s.borderBottom1PX, _s.bgSubtle, _s.borderColorSecondary, _s.jcCenter].join(' ')}>
<Heading size='h2'>
<Icon id='trends' className={[_s.mr10].join(' ')} size='18px' />
Headlines
<div className={[_s.d, _s.mb15].join(' ')}>
<div className={[_s.d, _s.px15, _s.py10, _s.borderBottom1PX, _s.bgSubtle, _s.borderColorSecondary, _s.jcCenter].join(' ')}>
<Heading size='h2'>
<Icon id='trends' className={[_s.mr10].join(' ')} size='18px' />
Headlines
</Heading>
</div>
{
leadHeadlines.map((lead) => (
<Button
isText
backgroundColor='none'
color='primary'
className={[_s.d, _s.py7].join(' ')}
href={`https://trends.gab.com/trend?url=${lead.href}`}
>
<Text>
{lead.title}
</Text>
</Button>
))
}
</div>
{
leadHeadlines.map((lead) => (
<Button
isText
backgroundColor='none'
color='primary'
className={[_s.d, _s.py7].join(' ')}
href={`https://trends.gab.com/trend?url=${lead.href}`}
>
<Text>
{lead.title}
</Text>
</Button>
))
}
</div>
}
<div>
@ -224,4 +199,24 @@ class News extends React.PureComponent {
)
}
}
}
const mapStateToProps = (state) => ({
isError: state.getIn(['gab_trends', 'partner', 'isError']),
isLoading: state.getIn(['gab_trends', 'partner', 'isLoading']),
items: state.getIn(['gab_trends', 'partner', 'items']),
})
const mapDispatchToProps = (dispatch) => ({
onfetchGabTrends: () => dispatch(fetchGabTrends('partner')),
})
News.propTypes = {
intl: PropTypes.object.isRequired,
isError: PropTypes.bool,
isLoading: PropTypes.bool,
items: PropTypes.object,
onfetchGabTrends: PropTypes.func.isRequired,
}
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(News))

View File

@ -20,45 +20,8 @@ import Block from '../components/block'
import Account from '../components/account'
import NotificationPlaceholder from '../components/placeholder/notification_placeholder'
const mapStateToProps = (state) => ({
notifications: state.getIn(['notifications', 'items']),
sortedNotifications: state.getIn(['notifications', 'sortedItems']),
isLoading: state.getIn(['notifications', 'isLoading'], true),
hasMore: state.getIn(['notifications', 'hasMore']),
totalQueuedNotificationsCount: state.getIn(['notifications', 'totalQueuedNotificationsCount'], 0),
selectedFilter: state.getIn(['notifications', 'filter', 'active']),
})
const mapDispatchToProps = (dispatch) => ({
onDequeueNotifications() {
dispatch(dequeueNotifications())
},
onExpandNotifications(options) {
if (!options) dispatch(forceDequeueNotifications())
dispatch(expandNotifications(options))
},
onScrollTopNotifications(top) {
dispatch(scrollTopNotifications(top))
},
})
export default
@withRouter
@connect(mapStateToProps, mapDispatchToProps)
class Notifications extends ImmutablePureComponent {
static propTypes = {
hasMore: PropTypes.bool,
isLoading: PropTypes.bool,
notifications: ImmutablePropTypes.list.isRequired,
onDequeueNotifications: PropTypes.func.isRequired,
onExpandNotifications: PropTypes.func.isRequired,
onScrollTopNotifications: PropTypes.func.isRequired,
sortedNotifications: ImmutablePropTypes.list.isRequired,
totalQueuedNotificationsCount: PropTypes.number,
selectedFilter: PropTypes.string.isRequired,
}
state = {
changedTabs: false,
}
@ -189,3 +152,39 @@ class Notifications extends ImmutablePureComponent {
}
}
const mapStateToProps = (state) => ({
notifications: state.getIn(['notifications', 'items']),
sortedNotifications: state.getIn(['notifications', 'sortedItems']),
isLoading: state.getIn(['notifications', 'isLoading'], true),
hasMore: state.getIn(['notifications', 'hasMore']),
totalQueuedNotificationsCount: state.getIn(['notifications', 'totalQueuedNotificationsCount'], 0),
selectedFilter: state.getIn(['notifications', 'filter', 'active']),
})
const mapDispatchToProps = (dispatch) => ({
onDequeueNotifications() {
dispatch(dequeueNotifications())
},
onExpandNotifications(options) {
if (!options) dispatch(forceDequeueNotifications())
dispatch(expandNotifications(options))
},
onScrollTopNotifications(top) {
dispatch(scrollTopNotifications(top))
},
})
Notifications.propTypes = {
hasMore: PropTypes.bool,
isLoading: PropTypes.bool,
notifications: ImmutablePropTypes.list.isRequired,
onDequeueNotifications: PropTypes.func.isRequired,
onExpandNotifications: PropTypes.func.isRequired,
onScrollTopNotifications: PropTypes.func.isRequired,
sortedNotifications: ImmutablePropTypes.list.isRequired,
totalQueuedNotificationsCount: PropTypes.number,
selectedFilter: PropTypes.string.isRequired,
}
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Notifications))

View File

@ -6,24 +6,12 @@ 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 React.PureComponent {
static contextTypes = {
router: PropTypes.object,
}
static propTypes = {
dispatch: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
}
componentDidMount () {
const { dispatch } = this.props
@ -61,3 +49,14 @@ class ProTimeline extends React.PureComponent {
}
}
const messages = defineMessages({
empty: { id: 'empty_column.pro', defaultMessage: 'The pro timeline is empty.' },
})
ProTimeline.propTypes = {
dispatch: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
}
export default injectIntl(connect(null)(ProTimeline))

View File

@ -14,26 +14,8 @@ import PanelLayout from '../components/panel/panel_layout'
import ColumnIndicator from '../components/column_indicator'
import Block from '../components/block'
const mapStateToProps = (state) => ({
isError: state.getIn(['search', 'isError']),
isLoading: state.getIn(['search', 'isLoading']),
results: state.getIn(['search', 'results']),
submitted: state.getIn(['search', 'submitted']),
});
export default
@withRouter
@connect(mapStateToProps)
class Search extends ImmutablePureComponent {
static propTypes = {
isError: PropTypes.bool.isRequired,
isLoading: PropTypes.bool.isRequired,
location: PropTypes.object,
results: ImmutablePropTypes.map.isRequired,
submitted: PropTypes.bool.isRequired,
}
state = {
isSmallScreen: (window.innerWidth <= 895),
}
@ -193,3 +175,20 @@ class Search extends ImmutablePureComponent {
}
}
const mapStateToProps = (state) => ({
isError: state.getIn(['search', 'isError']),
isLoading: state.getIn(['search', 'isLoading']),
results: state.getIn(['search', 'results']),
submitted: state.getIn(['search', 'submitted']),
})
Search.propTypes = {
isError: PropTypes.bool.isRequired,
isLoading: PropTypes.bool.isRequired,
location: PropTypes.object,
results: ImmutablePropTypes.map.isRequired,
submitted: PropTypes.bool.isRequired,
}
export default withRouter(connect(mapStateToProps)(Search))

View File

@ -7,29 +7,8 @@ import { fetchShortcuts } from '../actions/shortcuts'
import ColumnIndicator from '../components/column_indicator'
import List from '../components/list'
const mapStateToProps = (state) => ({
isError: state.getIn(['shortcuts', 'isError']),
isLoading: state.getIn(['shortcuts', 'isLoading']),
shortcuts: state.getIn(['shortcuts', 'items']),
})
const mapDispatchToProps = (dispatch) => ({
onFetchShortcuts() {
dispatch(fetchShortcuts())
},
})
export default
@connect(mapStateToProps, mapDispatchToProps)
class Shortcuts extends ImmutablePureComponent {
static propTypes = {
isLoading: PropTypes.bool.isRequired,
isError: PropTypes.bool.isRequired,
onFetchShortcuts: PropTypes.func.isRequired,
shortcuts: ImmutablePropTypes.list,
}
componentDidMount() {
this.props.onFetchShortcuts()
}
@ -61,4 +40,25 @@ class Shortcuts extends ImmutablePureComponent {
)
}
}
}
const mapStateToProps = (state) => ({
isError: state.getIn(['shortcuts', 'isError']),
isLoading: state.getIn(['shortcuts', 'isLoading']),
shortcuts: state.getIn(['shortcuts', 'items']),
})
const mapDispatchToProps = (dispatch) => ({
onFetchShortcuts() {
dispatch(fetchShortcuts())
},
})
Shortcuts.propTypes = {
isLoading: PropTypes.bool.isRequired,
isError: PropTypes.bool.isRequired,
onFetchShortcuts: PropTypes.func.isRequired,
shortcuts: ImmutablePropTypes.list,
}
export default connect(mapStateToProps, mapDispatchToProps)(Shortcuts)

View File

@ -11,32 +11,8 @@ import {
import StatusContainer from '../containers/status_container'
import StatusPlaceholder from '../components/placeholder/status_placeholder'
const mapStateToProps = (state, props) => {
const statusId = props.id || props.params.statusId
return {
status: state.getIn(['statuses', statusId]),
}
}
const mapDispatchToProps = (dispatch) => ({
onFetchStatus: (id) => dispatch(fetchStatus(id)),
onFetchContext: (id) => dispatch(fetchContext(id)),
onFetchComments: (id) => dispatch(fetchComments(id)),
})
export default
@connect(mapStateToProps, mapDispatchToProps)
class Status extends ImmutablePureComponent {
static propTypes = {
onFetchContext: PropTypes.func.isRequired,
onFetchStatus: PropTypes.func.isRequired,
onFetchComments: PropTypes.func.isRequired,
params: PropTypes.object,
status: ImmutablePropTypes.map,
}
componentDidMount() {
const statusId = this.props.id || this.props.params.statusId
this.props.onFetchStatus(statusId)
@ -80,3 +56,27 @@ class Status extends ImmutablePureComponent {
}
}
const mapStateToProps = (state, props) => {
const statusId = props.id || props.params.statusId
return {
status: state.getIn(['statuses', statusId]),
}
}
const mapDispatchToProps = (dispatch) => ({
onFetchStatus: (id) => dispatch(fetchStatus(id)),
onFetchContext: (id) => dispatch(fetchContext(id)),
onFetchComments: (id) => dispatch(fetchComments(id)),
})
Status.propTypes = {
onFetchContext: PropTypes.func.isRequired,
onFetchStatus: PropTypes.func.isRequired,
onFetchComments: PropTypes.func.isRequired,
params: PropTypes.object,
status: ImmutablePropTypes.map,
}
export default connect(mapStateToProps, mapDispatchToProps)(Status)

View File

@ -11,30 +11,8 @@ import Account from '../components/account'
import ColumnIndicator from '../components/column_indicator'
import ScrollableList from '../components/scrollable_list'
const mapStateToProps = (state, props) => {
const getStatus = makeGetStatus()
const status = getStatus(state, {
id: props.params.statusId,
username: props.params.username,
})
return {
status,
accountIds: state.getIn(['user_lists', 'liked_by', props.params.statusId]),
}
}
export default
@connect(mapStateToProps)
class StatusReposts extends ImmutablePureComponent {
static propTypes = {
params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
accountIds: ImmutablePropTypes.list,
status: ImmutablePropTypes.map,
}
componentWillMount () {
this.props.dispatch(fetchLikes(this.props.params.statusId))
this.props.dispatch(fetchStatus(this.props.params.statusId))
@ -71,3 +49,25 @@ class StatusReposts extends ImmutablePureComponent {
}
}
const mapStateToProps = (state, props) => {
const getStatus = makeGetStatus()
const status = getStatus(state, {
id: props.params.statusId,
username: props.params.username,
})
return {
status,
accountIds: state.getIn(['user_lists', 'liked_by', props.params.statusId]),
}
}
StatusReposts.propTypes = {
params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
accountIds: ImmutablePropTypes.list,
status: ImmutablePropTypes.map,
}
export default connect(mapStateToProps)(StatusReposts)

View File

@ -11,30 +11,8 @@ import Account from '../components/account'
import ColumnIndicator from '../components/column_indicator'
import ScrollableList from '../components/scrollable_list'
const mapStateToProps = (state, props) => {
const getStatus = makeGetStatus()
const status = getStatus(state, {
id: props.params.statusId,
username: props.params.username,
})
return {
status,
accountIds: state.getIn(['user_lists', 'reblogged_by', props.params.statusId]),
}
}
export default
@connect(mapStateToProps)
class StatusReposts extends ImmutablePureComponent {
static propTypes = {
params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
accountIds: ImmutablePropTypes.list,
status: ImmutablePropTypes.map,
}
componentWillMount () {
this.props.dispatch(fetchReposts(this.props.params.statusId))
this.props.dispatch(fetchStatus(this.props.params.statusId))
@ -71,3 +49,25 @@ class StatusReposts extends ImmutablePureComponent {
}
}
const mapStateToProps = (state, props) => {
const getStatus = makeGetStatus()
const status = getStatus(state, {
id: props.params.statusId,
username: props.params.username,
})
return {
status,
accountIds: state.getIn(['user_lists', 'reblogged_by', props.params.statusId]),
}
}
StatusReposts.propTypes = {
params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
accountIds: ImmutablePropTypes.list,
status: ImmutablePropTypes.map,
}
export default connect(mapStateToProps)(StatusReposts)

View File

@ -26,7 +26,6 @@ export function Following() { return import(/* webpackChunkName: "features/follo
export function FollowRequests() { return import(/* webpackChunkName: "features/follow_requests" */'../../follow_requests') }
export function LikedStatuses() { return import(/* webpackChunkName: "features/liked_statuses" */'../../liked_statuses') }
export function GenericNotFound() { return import(/* webpackChunkName: "features/generic_not_found" */'../../generic_not_found') }
export function GifPickerModal() { return import(/* webpackChunkName: "components/gif_picker_modal" */'../../../components/modal/gif_picker_modal') }
export function GlobalFooter() { return import(/* webpackChunkName: "components/global_footer" */'../../../components/global_footer') }
export function GroupsCollection() { return import(/* webpackChunkName: "features/groups_collection" */'../../groups_collection') }
export function GroupAbout() { return import(/* webpackChunkName: "features/group_about" */'../../group_about.js') }
@ -86,7 +85,6 @@ export function Shortcuts() { return import(/*webpackChunkName: "features/shortc
export function Status() { return import(/* webpackChunkName: "components/status" */'../../../components/status') }
export function StatusFeature() { return import(/* webpackChunkName: "features/status" */'../../status') }
export function SearchFilterPanel() { return import(/* webpackChunkName: "components/search_filter_panel" */'../../../components/panel/search_filter_panel') }
export function SearchPopover() { return import(/* webpackChunkName: "components/search_popover" */'../../../components/popover/search_popover') }
export function ShopPanel() { return import(/* webpackChunkName: "components/shop_panel" */'../../../components/panel/shop_panel') }
export function SidebarMorePopover() { return import(/* webpackChunkName: "components/sidebar_more_popover" */'../../../components/popover/sidebar_more_popover') }
export function SignUpLogInPanel() { return import(/* webpackChunkName: "components/sign_up_log_in_panel" */'../../../components/panel/sign_up_log_in_panel') }

View File

@ -36,7 +36,7 @@ class ProfileLayout extends ImmutablePureComponent {
const mainContentClasses = CX({
d: 1,
width645PX: !noSidebar,
w645PX: !noSidebar,
w1015PX: noSidebar,
z1: 1,
})

View File

@ -37,7 +37,6 @@ import statuses from './statuses'
import status_lists from './status_lists'
import status_revisions from './status_revisions'
import suggestions from './suggestions'
import tenor from './tenor'
import timelines from './timelines'
import toasts from './toasts'
import user from './user'
@ -82,7 +81,6 @@ const reducers = {
status_lists,
status_revisions,
suggestions,
tenor,
timelines,
toasts,
user,

Some files were not shown because too many files have changed in this diff Show More