Progress, Deck done
This commit is contained in:
parent
8f94ffad9c
commit
04053c0e31
@ -1,16 +1,23 @@
|
|||||||
import throttle from 'lodash.throttle'
|
import debounce from 'lodash.debounce'
|
||||||
import api, { getLinks } from '../api'
|
import api, { getLinks } from '../api'
|
||||||
import { importFetchedAccounts } from './importer'
|
import { importFetchedAccounts } from './importer'
|
||||||
import { me } from '../initial_state'
|
import { me } from '../initial_state'
|
||||||
|
|
||||||
export const CHAT_CONVERSATION_CREATE_SEARCH_ACCOUNTS_SUCCESS = 'CHAT_CONVERSATION_CREATE_SEARCH_ACCOUNTS_SUCCESS'
|
export const CHAT_CONVERSATION_CREATE_SEARCH_ACCOUNTS_SUCCESS = 'CHAT_CONVERSATION_CREATE_SEARCH_ACCOUNTS_SUCCESS'
|
||||||
|
|
||||||
|
export const CLEAR_CHAT_CONVERSATION_CREATE_SEARCH_ACCOUNTS = 'CLEAR_CHAT_CONVERSATION_CREATE_SEARCH_ACCOUNTS'
|
||||||
|
|
||||||
export const SET_CHAT_CONVERSATION_SELECTED = 'SET_CHAT_CONVERSATION_SELECTED'
|
export const SET_CHAT_CONVERSATION_SELECTED = 'SET_CHAT_CONVERSATION_SELECTED'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export const fetchChatConversationAccountSuggestions = (query) => throttle((dispatch, getState) => {
|
export const fetchChatConversationAccountSuggestions = (query) => (dispatch, getState) => {
|
||||||
|
if (!query) return
|
||||||
|
debouncedFetchChatConversationAccountSuggestions(query, dispatch, getState)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const debouncedFetchChatConversationAccountSuggestions = debounce((query, dispatch, getState) => {
|
||||||
if (!query) return
|
if (!query) return
|
||||||
|
|
||||||
api(getState).get('/api/v1/accounts/search', {
|
api(getState).get('/api/v1/accounts/search', {
|
||||||
@ -25,13 +32,20 @@ export const fetchChatConversationAccountSuggestions = (query) => throttle((disp
|
|||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
//
|
//
|
||||||
})
|
})
|
||||||
}, 200, { leading: true, trailing: true })
|
}, 650, { leading: true })
|
||||||
|
|
||||||
const fetchChatConversationAccountSuggestionsSuccess = (accounts) => ({
|
const fetchChatConversationAccountSuggestionsSuccess = (accounts) => ({
|
||||||
type: CHAT_CONVERSATION_CREATE_SEARCH_ACCOUNTS_SUCCESS,
|
type: CHAT_CONVERSATION_CREATE_SEARCH_ACCOUNTS_SUCCESS,
|
||||||
accounts,
|
accounts,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export const clearChatConversationAccountSuggestions = () => (dispatch) => {
|
||||||
|
dispatch({ type: CLEAR_CHAT_CONVERSATION_CREATE_SEARCH_ACCOUNTS })
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -41,6 +41,7 @@ export const COMPOSE_QUOTE = 'COMPOSE_QUOTE'
|
|||||||
export const COMPOSE_REPLY_CANCEL = 'COMPOSE_REPLY_CANCEL'
|
export const COMPOSE_REPLY_CANCEL = 'COMPOSE_REPLY_CANCEL'
|
||||||
export const COMPOSE_MENTION = 'COMPOSE_MENTION'
|
export const COMPOSE_MENTION = 'COMPOSE_MENTION'
|
||||||
export const COMPOSE_RESET = 'COMPOSE_RESET'
|
export const COMPOSE_RESET = 'COMPOSE_RESET'
|
||||||
|
export const COMPOSE_GROUP_SET = 'COMPOSE_GROUP_SET'
|
||||||
|
|
||||||
export const COMPOSE_UPLOAD_REQUEST = 'COMPOSE_UPLOAD_REQUEST'
|
export const COMPOSE_UPLOAD_REQUEST = 'COMPOSE_UPLOAD_REQUEST'
|
||||||
export const COMPOSE_UPLOAD_SUCCESS = 'COMPOSE_UPLOAD_SUCCESS'
|
export const COMPOSE_UPLOAD_SUCCESS = 'COMPOSE_UPLOAD_SUCCESS'
|
||||||
@ -762,6 +763,14 @@ export const changeExpiresAt = (value) => ({
|
|||||||
value,
|
value,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export const changeComposeGroupId = (groupId) => ({
|
||||||
|
type: COMPOSE_GROUP_SET,
|
||||||
|
groupId,
|
||||||
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
|
import debounce from 'lodash.debounce'
|
||||||
|
import api from '../api'
|
||||||
import { me } from '../initial_state'
|
import { me } from '../initial_state'
|
||||||
import { saveSettings } from './settings'
|
import { saveSettings } from './settings'
|
||||||
|
import { importFetchedAccounts } from './importer'
|
||||||
|
|
||||||
export const DECK_CONNECT = 'DECK_CONNECT'
|
export const DECK_CONNECT = 'DECK_CONNECT'
|
||||||
export const DECK_DISCONNECT = 'DECK_DISCONNECT'
|
export const DECK_DISCONNECT = 'DECK_DISCONNECT'
|
||||||
@ -8,6 +11,9 @@ export const DECK_SET_COLUMN_AT_INDEX = 'DECK_SET_COLUMN_AT_INDEX'
|
|||||||
export const DECK_DELETE_COLUMN_AT_INDEX = 'DECK_DELETE_COLUMN_AT_INDEX'
|
export const DECK_DELETE_COLUMN_AT_INDEX = 'DECK_DELETE_COLUMN_AT_INDEX'
|
||||||
export const DECK_CHANGE_COLUMN_AT_INDEX = 'DECK_CHANGE_COLUMN_AT_INDEX'
|
export const DECK_CHANGE_COLUMN_AT_INDEX = 'DECK_CHANGE_COLUMN_AT_INDEX'
|
||||||
|
|
||||||
|
export const DECK_SEARCH_USERS_SUCCESS = 'DECK_SEARCH_USERS_SUCCESS'
|
||||||
|
export const DECK_SEARCH_USERS_CLEAR = 'DECK_SEARCH_USERS_CLEAR'
|
||||||
|
|
||||||
export const deckConnect = () => ({
|
export const deckConnect = () => ({
|
||||||
type: DECK_CONNECT,
|
type: DECK_CONNECT,
|
||||||
})
|
})
|
||||||
@ -41,3 +47,40 @@ export const updateDeckColumnAtIndex = (oldIndex, newIndex) => (dispatch) => {
|
|||||||
})
|
})
|
||||||
dispatch(saveSettings())
|
dispatch(saveSettings())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export const fetchDeckAccountSuggestions = (query) => (dispatch, getState) => {
|
||||||
|
if (!query) return
|
||||||
|
debouncedFetchDeckAccountSuggestions(query, dispatch, getState)
|
||||||
|
}
|
||||||
|
|
||||||
|
const debouncedFetchDeckAccountSuggestions = debounce((query, dispatch, getState) => {
|
||||||
|
if (!query) return
|
||||||
|
|
||||||
|
api(getState).get('/api/v1/accounts/search', {
|
||||||
|
params: {
|
||||||
|
q: query,
|
||||||
|
resolve: false,
|
||||||
|
limit: 4,
|
||||||
|
},
|
||||||
|
}).then((response) => {
|
||||||
|
dispatch(importFetchedAccounts(response.data))
|
||||||
|
dispatch(fetchDeckAccountSuggestionsSuccess(response.data))
|
||||||
|
}).catch((error) => {
|
||||||
|
//
|
||||||
|
})
|
||||||
|
}, 650, { leading: true })
|
||||||
|
|
||||||
|
const fetchDeckAccountSuggestionsSuccess = (accounts) => ({
|
||||||
|
type: DECK_SEARCH_USERS_SUCCESS,
|
||||||
|
accounts,
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export const clearDeckAccountSuggestions = () => (dispatch) => {
|
||||||
|
dispatch({ type: DECK_SEARCH_USERS_CLEAR })
|
||||||
|
}
|
@ -1,8 +1,82 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||||
|
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
|
import { fetchAccount } from '../actions/accounts'
|
||||||
import DeckColumnHeader from './deck_column_header'
|
import DeckColumnHeader from './deck_column_header'
|
||||||
|
import Avatar from './avatar'
|
||||||
|
import DisplayName from './display_name'
|
||||||
|
import {
|
||||||
|
FONT_SIZES,
|
||||||
|
DEFAULT_FONT_SIZE,
|
||||||
|
FONT_SIZES_EXTRA_SMALL,
|
||||||
|
FONT_SIZES_SMALL,
|
||||||
|
FONT_SIZES_NORMAL,
|
||||||
|
FONT_SIZES_MEDIUM,
|
||||||
|
FONT_SIZES_LARGE,
|
||||||
|
FONT_SIZES_EXTRA_LARGE
|
||||||
|
} from '../constants'
|
||||||
|
|
||||||
class DeckColumn extends React.PureComponent {
|
class DeckColumn extends ImmutablePureComponent {
|
||||||
|
|
||||||
|
state = {
|
||||||
|
width: 360, // default
|
||||||
|
refreshBool: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.setWidth()
|
||||||
|
|
||||||
|
const { accountId, account } = this.props
|
||||||
|
if (!!accountId || !account) {
|
||||||
|
this.props.onFetchAccount(accountId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps) {
|
||||||
|
if (prevProps.fontSize !== this.props.fontSize) {
|
||||||
|
this.setWidth()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setWidth = () => {
|
||||||
|
const { fontSize } = this.props
|
||||||
|
|
||||||
|
let width = 360
|
||||||
|
switch (FONT_SIZES[fontSize]) {
|
||||||
|
case FONT_SIZES_EXTRA_SMALL:
|
||||||
|
width = 310
|
||||||
|
break;
|
||||||
|
case FONT_SIZES_SMALL:
|
||||||
|
width = 320
|
||||||
|
break;
|
||||||
|
case FONT_SIZES_NORMAL:
|
||||||
|
width = 335
|
||||||
|
break;
|
||||||
|
case FONT_SIZES_MEDIUM:
|
||||||
|
width = 350
|
||||||
|
break;
|
||||||
|
case FONT_SIZES_LARGE:
|
||||||
|
width = 365
|
||||||
|
break;
|
||||||
|
case FONT_SIZES_EXTRA_LARGE:
|
||||||
|
width = 385
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({ width })
|
||||||
|
}
|
||||||
|
|
||||||
|
handleOnRefresh = () => {
|
||||||
|
//hacky
|
||||||
|
this.setState({ refreshBool: true })
|
||||||
|
setTimeout(() => {
|
||||||
|
this.setState({ refreshBool: false })
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
@ -12,20 +86,38 @@ class DeckColumn extends React.PureComponent {
|
|||||||
children,
|
children,
|
||||||
index,
|
index,
|
||||||
noButtons,
|
noButtons,
|
||||||
|
noRefresh,
|
||||||
|
account,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
const { width, refreshBool } = this.state
|
||||||
|
|
||||||
|
let newTitle = title
|
||||||
|
if (!!account) {
|
||||||
|
|
||||||
|
newTitle = (
|
||||||
|
<div className={[_s.d, _s.flexRow, _s.aiCenter].join(' ')}>
|
||||||
|
<Avatar account={account} noHover size={30} />
|
||||||
|
<div className={[_s.d, _s.ml10].join(' ')}>
|
||||||
|
<DisplayName account={account} noUsername isInline noHover />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={[_s.d, _s.w360PX, _s.px2, _s.bgSecondary, _s.h100VH].join(' ')}>
|
<div className={[_s.d, _s.px2, _s.bgSecondary, _s.h100VH].join(' ')} style={{ width: `${width}px` }}>
|
||||||
<div className={[_s.d, _s.w100PC, _s.bgPrimary, _s.h100VH].join(' ')}>
|
<div className={[_s.d, _s.w100PC, _s.bgPrimary, _s.h100VH].join(' ')}>
|
||||||
<DeckColumnHeader
|
<DeckColumnHeader
|
||||||
title={title}
|
title={newTitle}
|
||||||
subtitle={subtitle}
|
subtitle={subtitle}
|
||||||
icon={icon}
|
icon={icon}
|
||||||
index={index}
|
index={index}
|
||||||
noButtons={noButtons}
|
noButtons={noButtons}
|
||||||
|
noRefresh={noRefresh}
|
||||||
|
onRefresh={this.handleOnRefresh}
|
||||||
/>
|
/>
|
||||||
<div className={[_s.d, _s.w100PC, _s.overflowYScroll, _s.boxShadowNone, _s.posAbs, _s.top60PX, _s.left0, _s.right0, _s.bottom0].join(' ')}>
|
<div className={[_s.d, _s.w100PC, _s.overflowYScroll, _s.boxShadowNone, _s.posAbs, _s.top60PX, _s.left0, _s.right0, _s.bottom0].join(' ')}>
|
||||||
{children}
|
{ !refreshBool && children}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -34,12 +126,32 @@ class DeckColumn extends React.PureComponent {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = (state, { accountId }) => {
|
||||||
|
const account = !!accountId ? state.getIn(['accounts', accountId]) : null
|
||||||
|
|
||||||
|
return {
|
||||||
|
account,
|
||||||
|
fontSize: state.getIn(['settings', 'displayOptions', 'fontSize'], DEFAULT_FONT_SIZE),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
onFetchAccount(accountId) {
|
||||||
|
dispatch(fetchAccount(accountId))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
DeckColumn.propTypes = {
|
DeckColumn.propTypes = {
|
||||||
title: PropTypes.string,
|
title: PropTypes.string,
|
||||||
subtitle: PropTypes.string,
|
subtitle: PropTypes.string,
|
||||||
icon: PropTypes.string,
|
icon: PropTypes.string,
|
||||||
index: PropTypes.number,
|
index: PropTypes.number,
|
||||||
noButtons: PropTypes.bool,
|
noButtons: PropTypes.bool,
|
||||||
|
noRefresh: PropTypes.bool,
|
||||||
|
onRefresh: PropTypes.func,
|
||||||
|
accountId: PropTypes.string,
|
||||||
|
account: ImmutablePropTypes.map,
|
||||||
|
onFetchAccount: PropTypes.func.isRequired,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default DeckColumn
|
export default connect(mapStateToProps, mapDispatchToProps)(DeckColumn)
|
@ -13,7 +13,8 @@ class DeckColumnHeader extends React.PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleClickRefresh = () => {
|
handleClickRefresh = () => {
|
||||||
|
const { onRefresh } = this.props
|
||||||
|
if (!!onRefresh) onRefresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -23,34 +24,36 @@ class DeckColumnHeader extends React.PureComponent {
|
|||||||
icon,
|
icon,
|
||||||
children,
|
children,
|
||||||
noButtons,
|
noButtons,
|
||||||
|
noRefresh,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div data-sort-header className={[_s.d, _s.w100PC, _s.flexRow, _s.aiCenter, _s.h60PX, _s.px15, _s.py10, _s.borderBottom1PX, _s.borderColorSecondary, _s.bgPrimary].join(' ')}>
|
<div data-sort-header className={[_s.d, _s.w100PC, _s.flexRow, _s.aiCenter, _s.h60PX, _s.px15, _s.py10, _s.borderBottom1PX, _s.borderColorSecondary, _s.bgPrimary].join(' ')}>
|
||||||
{
|
<div data-sort-header className={[_s.d, _s.flexRow, _s.mr15, _s.cursorEWResize].join(' ')}>
|
||||||
!!icon &&
|
<span className={[_s.d, _s.w1PX, _s.h24PX, _s.mr2, _s.bgSecondary].join(' ')} />
|
||||||
<div data-sort-header className={[_s.d, _s.flexRow, _s.mr15, _s.cursorEWResize].join(' ')}>
|
<span className={[_s.d, _s.w1PX, _s.h24PX, _s.mr2, _s.bgSecondary].join(' ')} />
|
||||||
<span className={[_s.d, _s.w1PX, _s.h24PX, _s.mr2, _s.bgSecondary].join(' ')} />
|
<span className={[_s.d, _s.w1PX, _s.h24PX, _s.bgSecondary].join(' ')} />
|
||||||
<span className={[_s.d, _s.w1PX, _s.h24PX, _s.mr2, _s.bgSecondary].join(' ')} />
|
</div>
|
||||||
<span className={[_s.d, _s.w1PX, _s.h24PX, _s.bgSecondary].join(' ')} />
|
|
||||||
</div>
|
{ !!icon && <Icon id={icon} className={[_s.cPrimary, _s.mr15].join(' ')} size='18px' /> }
|
||||||
}
|
<div className={[_s.d, _s.flexRow, _s.aiEnd].join(' ')}>
|
||||||
{ !!icon && <Icon id={icon} className={_s.cPrimary} size='18px' /> }
|
|
||||||
<div className={[_s.d, _s.flexRow, _s.aiEnd, _s.ml15].join(' ')}>
|
|
||||||
{ !!title && <Text size='extraLarge' weight='medium'>{title}</Text> }
|
{ !!title && <Text size='extraLarge' weight='medium'>{title}</Text> }
|
||||||
{ !!subtitle && <Text className={_s.ml5} color='secondary'>{subtitle}</Text> }
|
{ !!subtitle && <Text className={_s.ml5} color='secondary'>{subtitle}</Text> }
|
||||||
</div>
|
</div>
|
||||||
{
|
{
|
||||||
!!title && !noButtons &&
|
!!title && !noButtons &&
|
||||||
<div className={[_s.d, _s.flexRow, _s.aiCenter, _s.mlAuto, _s.jcCenter].join(' ')}>
|
<div className={[_s.d, _s.flexRow, _s.aiCenter, _s.mlAuto, _s.jcCenter].join(' ')}>
|
||||||
<Button
|
{
|
||||||
isNarrow
|
!noRefresh &&
|
||||||
noClasses
|
<Button
|
||||||
onClick={this.handleClickRefresh}
|
isNarrow
|
||||||
className={[_s.d, _s.mr5, _s.cursorPointer, _s.outlineNone, _s.bgTransparent, _s.px5, _s.py5].join(' ')}
|
noClasses
|
||||||
iconClassName={_s.cSecondary}
|
onClick={this.handleClickRefresh}
|
||||||
icon='repost'
|
className={[_s.d, _s.mr5, _s.cursorPointer, _s.outlineNone, _s.bgTransparent, _s.px5, _s.py5].join(' ')}
|
||||||
/>
|
iconClassName={_s.cSecondary}
|
||||||
|
icon='repost'
|
||||||
|
/>
|
||||||
|
}
|
||||||
<Button
|
<Button
|
||||||
isNarrow
|
isNarrow
|
||||||
noClasses
|
noClasses
|
||||||
@ -73,6 +76,8 @@ DeckColumnHeader.propTypes = {
|
|||||||
icon: PropTypes.string,
|
icon: PropTypes.string,
|
||||||
index: PropTypes.number,
|
index: PropTypes.number,
|
||||||
noButtons: PropTypes.bool,
|
noButtons: PropTypes.bool,
|
||||||
|
noRefresh: PropTypes.bool,
|
||||||
|
onRefresh: PropTypes.func,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect()(DeckColumnHeader)
|
export default connect()(DeckColumnHeader)
|
@ -7,13 +7,19 @@ import { openModal } from '../../actions/modal'
|
|||||||
import { setDeckColumnAtIndex } from '../../actions/deck'
|
import { setDeckColumnAtIndex } from '../../actions/deck'
|
||||||
import { getOrderedLists, getListOfGroups } from '../../selectors'
|
import { getOrderedLists, getListOfGroups } from '../../selectors'
|
||||||
import { fetchLists } from '../../actions/lists'
|
import { fetchLists } from '../../actions/lists'
|
||||||
|
import {
|
||||||
|
fetchDeckAccountSuggestions,
|
||||||
|
clearDeckAccountSuggestions,
|
||||||
|
} from '../../actions/deck'
|
||||||
import { fetchGroupsByTab } from '../../actions/groups'
|
import { fetchGroupsByTab } from '../../actions/groups'
|
||||||
import { MODAL_DECK_COLUMN_ADD } from '../../constants'
|
import { MODAL_DECK_COLUMN_ADD } from '../../constants'
|
||||||
|
import Account from '../account'
|
||||||
import Heading from '../heading'
|
import Heading from '../heading'
|
||||||
import Button from '../button'
|
import Button from '../button'
|
||||||
import Block from '../block'
|
import Block from '../block'
|
||||||
import Input from '../input'
|
import Input from '../input'
|
||||||
import List from '../list'
|
import List from '../list'
|
||||||
|
import Text from '../text'
|
||||||
|
|
||||||
class DeckColumnAddOptionsModal extends ImmutablePureComponent {
|
class DeckColumnAddOptionsModal extends ImmutablePureComponent {
|
||||||
|
|
||||||
@ -50,17 +56,24 @@ class DeckColumnAddOptionsModal extends ImmutablePureComponent {
|
|||||||
this.setState({ hashtagValue: '' })
|
this.setState({ hashtagValue: '' })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleAddUser = (userId) => {
|
||||||
|
this.setState({ usernameValue: '' })
|
||||||
|
this.props.onClearDeckAccountSuggestions()
|
||||||
|
if (!!userId) this.handleAdd(`user.${userId}`)
|
||||||
|
}
|
||||||
|
|
||||||
onChangeHashtagValue = (hashtagValue) => {
|
onChangeHashtagValue = (hashtagValue) => {
|
||||||
this.setState({ hashtagValue })
|
this.setState({ hashtagValue })
|
||||||
}
|
}
|
||||||
|
|
||||||
onChangeUsernameValue = (usernameValue) => {
|
onChangeUsernameValue = (usernameValue) => {
|
||||||
this.setState({ usernameValue })
|
this.setState({ usernameValue })
|
||||||
|
this.props.onFetchUserSuggestions(usernameValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
getContentForColumn = () => {
|
getContentForColumn = () => {
|
||||||
const { column, lists, groups, accounts } = this.props
|
const { column, lists, groups, suggestionsIds } = this.props
|
||||||
const { hashtagValue } = this.state
|
const { hashtagValue, usernameValue } = this.state
|
||||||
|
|
||||||
if (column === 'hashtag') {
|
if (column === 'hashtag') {
|
||||||
return (
|
return (
|
||||||
@ -107,17 +120,39 @@ class DeckColumnAddOptionsModal extends ImmutablePureComponent {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
} else if (column === 'group') {
|
} else if (column === 'user') {
|
||||||
return (
|
return (
|
||||||
<div className={[_s.d, _s.px15, _s.py10].join(' ')}>
|
<div className={[_s.d, _s.width100PC].join(' ')}>
|
||||||
<Input
|
<div className={[_s.d, _s.px15, _s.py10].join(' ')}>
|
||||||
type='text'
|
<Input
|
||||||
value={usernameValue}
|
type='text'
|
||||||
placeholder=''
|
value={usernameValue}
|
||||||
id='user-deck'
|
placeholder=''
|
||||||
title='Enter username'
|
id='user-deck'
|
||||||
onChange={this.onChangeUsernameValue}
|
title='Enter username'
|
||||||
/>
|
onChange={this.onChangeUsernameValue}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={[_s.d, _s.pt10].join(' ')}>
|
||||||
|
<div className={[_s.d].join(' ')}>
|
||||||
|
<Text weight='bold' size='small' color='secondary' className={[_s.d, _s.px15, _s.ml15, _s.mt5, _s.mb15].join(' ')}>
|
||||||
|
Search results ({suggestionsIds.size})
|
||||||
|
</Text>
|
||||||
|
{
|
||||||
|
suggestionsIds &&
|
||||||
|
suggestionsIds.map((accountId) => (
|
||||||
|
<Account
|
||||||
|
compact
|
||||||
|
key={`create-deck-user-${accountId}`}
|
||||||
|
id={accountId}
|
||||||
|
onActionClick={() => this.handleAddUser(accountId)}
|
||||||
|
actionIcon='add'
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -175,7 +210,7 @@ class DeckColumnAddOptionsModal extends ImmutablePureComponent {
|
|||||||
const mapStateToProps = (state) => ({
|
const mapStateToProps = (state) => ({
|
||||||
lists: getOrderedLists(state),
|
lists: getOrderedLists(state),
|
||||||
groups: getListOfGroups(state, { type: 'member' }),
|
groups: getListOfGroups(state, { type: 'member' }),
|
||||||
accounts: [],
|
suggestionsIds: state.getIn(['deck', 'accountSuggestions']),
|
||||||
})
|
})
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
@ -191,6 +226,12 @@ const mapDispatchToProps = (dispatch) => ({
|
|||||||
onOpenDeckColumnAddModal() {
|
onOpenDeckColumnAddModal() {
|
||||||
dispatch(openModal(MODAL_DECK_COLUMN_ADD))
|
dispatch(openModal(MODAL_DECK_COLUMN_ADD))
|
||||||
},
|
},
|
||||||
|
onFetchUserSuggestions(query) {
|
||||||
|
dispatch(fetchDeckAccountSuggestions(query))
|
||||||
|
},
|
||||||
|
onClearDeckAccountSuggestions() {
|
||||||
|
dispatch(clearDeckAccountSuggestions())
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
DeckColumnAddOptionsModal.propTypes = {
|
DeckColumnAddOptionsModal.propTypes = {
|
||||||
|
@ -1,74 +1,152 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||||
|
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
import { closePopover } from '../../actions/popover'
|
import { closePopover } from '../../actions/popover'
|
||||||
|
import { getListOfGroups } from '../../selectors'
|
||||||
|
import { fetchGroupsByTab } from '../../actions/groups'
|
||||||
|
import { changeComposeGroupId } from '../../actions/compose'
|
||||||
import PopoverLayout from './popover_layout'
|
import PopoverLayout from './popover_layout'
|
||||||
import List from '../list'
|
import List from '../list'
|
||||||
import Button from '../button'
|
import Button from '../button'
|
||||||
import Text from '../text'
|
import Text from '../text'
|
||||||
|
|
||||||
class ComposePostDesinationPopover extends React.PureComponent {
|
class ComposePostDesinationPopover extends ImmutablePureComponent {
|
||||||
|
|
||||||
|
state = {
|
||||||
|
isGroupsSelected: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
if (this.props.composeGroupId) {
|
||||||
|
this.setState({ isGroupsSelected: true })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate (prevProps) {
|
||||||
|
if (prevProps.composeGroupId !== this.props.composeGroupId) {
|
||||||
|
this.setState({ isGroupsSelected: !!this.props.composeGroupId })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
handleOnClosePopover = () => {
|
handleOnClosePopover = () => {
|
||||||
this.props.onClosePopover()
|
this.props.onClosePopover()
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
selectDestination = (destination) => {
|
||||||
const {
|
const isGroupsSelected = destination === 'group'
|
||||||
isXS,
|
this.setState({ isGroupsSelected })
|
||||||
} = this.props
|
if (isGroupsSelected) {
|
||||||
|
this.props.onFetchMemberGroups()
|
||||||
|
} else {
|
||||||
|
this.handleSelectGroup(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TIMELINE
|
handleSelectGroup = (groupId) => {
|
||||||
// GROUP - MY GROUPS
|
this.props.onChangeComposeGroupId(groupId)
|
||||||
|
this.handleOnClosePopover()
|
||||||
const items = [
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { isXS, groups, composeGroupId } = this.props
|
||||||
|
const { isGroupsSelected } = this.state
|
||||||
|
|
||||||
|
const mainItems = [
|
||||||
{
|
{
|
||||||
hideArrow: true,
|
hideArrow: true,
|
||||||
title: 'Timeline',
|
title: 'Timeline',
|
||||||
onClick: () => this.handleOnDelete(),
|
isActive: !isGroupsSelected,
|
||||||
|
onClick: () => this.selectDestination('home'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Group',
|
title: 'Group',
|
||||||
onClick: () => this.handleOnReport(),
|
isActive: isGroupsSelected,
|
||||||
|
onClick: () => this.selectDestination('group'),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const groupItems = !!groups ? groups.map((group) => ({
|
||||||
|
hideArrow: true,
|
||||||
|
onClick: () => this.handleSelectGroup(group.get('id')),
|
||||||
|
title: group.get('title'),
|
||||||
|
isActive: group.get('id') === composeGroupId,
|
||||||
|
})) : []
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PopoverLayout
|
<PopoverLayout
|
||||||
width={180}
|
width={isGroupsSelected ? 320 : 180}
|
||||||
isXS={isXS}
|
isXS={isXS}
|
||||||
onClose={this.handleOnClosePopover}
|
onClose={this.handleOnClosePopover}
|
||||||
>
|
>
|
||||||
<div className={[_s.d]}>
|
{
|
||||||
<Text className={[_s.d, _s.px15, _s.py10, _s.bgSecondary].join(' ')}>Post to:</Text>
|
!isGroupsSelected &&
|
||||||
<List items={items} />
|
<div className={[_s.d, _s.w100PC].join(' ')}>
|
||||||
</div>
|
<Text className={[_s.d, _s.px15, _s.py10, _s.bgSecondary].join(' ')}>Post to:</Text>
|
||||||
<div>
|
<List items={mainItems} />
|
||||||
<Text className={[_s.d, _s.px15, _s.py10, _s.bgSecondary].join(' ')}>
|
</div>
|
||||||
<Button
|
}
|
||||||
isText
|
{
|
||||||
icon='back'
|
isGroupsSelected &&
|
||||||
/>
|
<div className={[_s.d, _s.w100PC].join(' ')}>
|
||||||
Select group:
|
<div className={[_s.d, _s.flexRow, _s.bgSecondary].join(' ')}>
|
||||||
</Text>
|
<Button
|
||||||
<List items={items} />
|
isText
|
||||||
</div>
|
icon='back'
|
||||||
|
color='primary'
|
||||||
|
backgroundColor='none'
|
||||||
|
className={[_s.aiCenter, _s.jcCenter, _s.pl15, _s.pr5].join(' ')}
|
||||||
|
onClick={() => this.selectDestination('home')}
|
||||||
|
/>
|
||||||
|
<Text className={[_s.d, _s.pl5, _s.py10].join(' ')}>
|
||||||
|
Select group:
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
<div className={[_s.d, _s.w100PC, _s.overflowYScroll, _s.maxH340PX].join(' ')}>
|
||||||
|
<List
|
||||||
|
scrollKey='groups-post-destination-add'
|
||||||
|
showLoading={groups.size === 0}
|
||||||
|
emptyMessage="You are not a member of any groups yet."
|
||||||
|
items={groupItems}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</PopoverLayout>
|
</PopoverLayout>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapStateToProps = (state) => ({
|
const mapStateToProps = (state) => {
|
||||||
//
|
const composeGroupId = state.getIn(['compose', 'group_id'])
|
||||||
})
|
|
||||||
|
return {
|
||||||
|
composeGroupId,
|
||||||
|
composeGroup: state.getIn(['groups', composeGroupId]),
|
||||||
|
groups: getListOfGroups(state, { type: 'member' }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
onClosePopover: () => dispatch(closePopover()),
|
onClosePopover() {
|
||||||
|
dispatch(closePopover())
|
||||||
|
},
|
||||||
|
onFetchMemberGroups() {
|
||||||
|
dispatch(fetchGroupsByTab('member'))
|
||||||
|
},
|
||||||
|
onChangeComposeGroupId(groupId) {
|
||||||
|
dispatch(changeComposeGroupId(groupId))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
ComposePostDesinationPopover.propTypes = {
|
ComposePostDesinationPopover.propTypes = {
|
||||||
isXS: PropTypes.bool,
|
isXS: PropTypes.bool,
|
||||||
onClosePopover: PropTypes.func.isRequired,
|
onClosePopover: PropTypes.func.isRequired,
|
||||||
|
onFetchMemberGroups: PropTypes.func.isRequired,
|
||||||
|
onChangeComposeGroupId: PropTypes.func.isRequired,
|
||||||
|
groups: ImmutablePropTypes.list,
|
||||||
|
composeGroup: ImmutablePropTypes.map,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(ComposePostDesinationPopover)
|
export default connect(mapStateToProps, mapDispatchToProps)(ComposePostDesinationPopover)
|
@ -3,7 +3,9 @@ import PropTypes from 'prop-types'
|
|||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
import { defineMessages, injectIntl } from 'react-intl'
|
import { defineMessages, injectIntl } from 'react-intl'
|
||||||
import { closePopover } from '../../actions/popover'
|
import { closePopover } from '../../actions/popover'
|
||||||
|
import { openModal } from '../../actions/modal'
|
||||||
import { meUsername } from '../../initial_state'
|
import { meUsername } from '../../initial_state'
|
||||||
|
import { MODAL_DISPLAY_OPTIONS } from '../../constants'
|
||||||
import PopoverLayout from './popover_layout'
|
import PopoverLayout from './popover_layout'
|
||||||
import List from '../list'
|
import List from '../list'
|
||||||
|
|
||||||
@ -13,6 +15,11 @@ class NavSettingsPopover extends React.PureComponent {
|
|||||||
this.props.onClosePopover()
|
this.props.onClosePopover()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleOpenDisplayOptions = () => {
|
||||||
|
this.props.onOpenDisplayOptions()
|
||||||
|
this.handleOnClosePopover()
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { intl, isXS } = this.props
|
const { intl, isXS } = this.props
|
||||||
|
|
||||||
@ -29,6 +36,10 @@ class NavSettingsPopover extends React.PureComponent {
|
|||||||
to: `/${meUsername}`,
|
to: `/${meUsername}`,
|
||||||
onClick: this.handleOnClosePopover,
|
onClick: this.handleOnClosePopover,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: 'Display options',
|
||||||
|
onClick: this.handleOpenDisplayOptions,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: intl.formatMessage(messages.help),
|
title: intl.formatMessage(messages.help),
|
||||||
href: 'https://help.gab.com',
|
href: 'https://help.gab.com',
|
||||||
@ -60,6 +71,9 @@ const mapDispatchToProps = (dispatch) => ({
|
|||||||
onClosePopover() {
|
onClosePopover() {
|
||||||
dispatch(closePopover())
|
dispatch(closePopover())
|
||||||
},
|
},
|
||||||
|
onOpenDisplayOptions() {
|
||||||
|
dispatch(openModal(MODAL_DISPLAY_OPTIONS))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
NavSettingsPopover.propTypes = {
|
NavSettingsPopover.propTypes = {
|
||||||
|
@ -175,7 +175,6 @@ export const TRENDS_RSS_SOURCES = [
|
|||||||
{'id':'5daf66772fea4d3ba000883b','title':'Gateway Pundit'},
|
{'id':'5daf66772fea4d3ba000883b','title':'Gateway Pundit'},
|
||||||
{'id':'5dafa767300c0e2601330386','title':'RT'},
|
{'id':'5dafa767300c0e2601330386','title':'RT'},
|
||||||
{'id':'5dafa88b786f593d02078d35','title':'ABC News'},
|
{'id':'5dafa88b786f593d02078d35','title':'ABC News'},
|
||||||
{'id':'5e1e0a479d78d445de6a32bd','title':'Aljazeera'},
|
|
||||||
{'id':'5e1e0a7dc46f1d5487be1806','title':'Yahoo News'},
|
{'id':'5e1e0a7dc46f1d5487be1806','title':'Yahoo News'},
|
||||||
{'id':'5e1e0ae5c46f1d5487be1902','title':'NBC'},
|
{'id':'5e1e0ae5c46f1d5487be1902','title':'NBC'},
|
||||||
{'id':'5e1e0b849d78d445de6a35c7','title':'LA Times'},
|
{'id':'5e1e0b849d78d445de6a35c7','title':'LA Times'},
|
||||||
@ -183,11 +182,8 @@ export const TRENDS_RSS_SOURCES = [
|
|||||||
{'id':'5e52dfc91f94b1111db105ed','title':'National File'},
|
{'id':'5e52dfc91f94b1111db105ed','title':'National File'},
|
||||||
{'id':'5e56dcff1f94b1111db95a75','title':'WND'},
|
{'id':'5e56dcff1f94b1111db95a75','title':'WND'},
|
||||||
{'id':'5e6423d39f964d7a761997f8','title':'Mediaite'},
|
{'id':'5e6423d39f964d7a761997f8','title':'Mediaite'},
|
||||||
{'id':'5e716016a994095d6ca9b907','title':'CNBC'},
|
|
||||||
{'id':'5e7160cb40c78e3a4af7a5bb','title':'FiveThirtyEight'},
|
{'id':'5e7160cb40c78e3a4af7a5bb','title':'FiveThirtyEight'},
|
||||||
{'id':'5e7160f7a994095d6ca9bbee','title':'Redstate'},
|
{'id':'5e7160f7a994095d6ca9bbee','title':'Redstate'},
|
||||||
{'id':'5e71613ca994095d6ca9bcbb','title':'Vice'},
|
|
||||||
{'id':'5e716155a994095d6ca9bd03','title':'Politico'},
|
{'id':'5e716155a994095d6ca9bd03','title':'Politico'},
|
||||||
{'id':'5e7161f3a994095d6ca9bea6','title':'TMZ'},
|
|
||||||
{'id':'5e8275900d86876052a853ae','title':'CD Media'},
|
{'id':'5e8275900d86876052a853ae','title':'CD Media'},
|
||||||
]
|
]
|
@ -95,9 +95,8 @@ const messages = defineMessages({
|
|||||||
|
|
||||||
const emptyList = ImmutableList()
|
const emptyList = ImmutableList()
|
||||||
|
|
||||||
const mapStateToProps = (state, { account, commentsOnly = false }) => {
|
const mapStateToProps = (state, { id, account, commentsOnly = false }) => {
|
||||||
const accountId = !!account ? account.getIn(['id'], null) : -1
|
const accountId = !!id ? id : !!account ? account.getIn(['id'], null) : -1
|
||||||
|
|
||||||
const path = commentsOnly ? `${accountId}:comments_only` : accountId
|
const path = commentsOnly ? `${accountId}:comments_only` : accountId
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
import { fetchChatConversationAccountSuggestions } from '../actions/chats'
|
import {
|
||||||
|
fetchChatConversationAccountSuggestions,
|
||||||
|
clearChatConversationAccountSuggestions,
|
||||||
|
} from '../actions/chats'
|
||||||
import { createChatConversation } from '../actions/chat_conversations'
|
import { createChatConversation } from '../actions/chat_conversations'
|
||||||
import Account from '../components/account'
|
import Account from '../components/account'
|
||||||
import Button from '../components/button'
|
import Button from '../components/button'
|
||||||
@ -22,6 +25,11 @@ class ChatConversationCreate extends React.PureComponent {
|
|||||||
|
|
||||||
handleOnCreateChatConversation = (accountId) => {
|
handleOnCreateChatConversation = (accountId) => {
|
||||||
this.props.onCreateChatConversation(accountId)
|
this.props.onCreateChatConversation(accountId)
|
||||||
|
this.props.onClearChatConversationAccountSuggestions()
|
||||||
|
|
||||||
|
if (this.props.isModal && !!this.props.onCloseModal) {
|
||||||
|
this.props.onCloseModal()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -47,7 +55,7 @@ class ChatConversationCreate extends React.PureComponent {
|
|||||||
suggestionsIds.map((accountId) => (
|
suggestionsIds.map((accountId) => (
|
||||||
<Account
|
<Account
|
||||||
compact
|
compact
|
||||||
key={`remove-from-list-${accountId}`}
|
key={`chat-conversation-account-create-${accountId}`}
|
||||||
id={accountId}
|
id={accountId}
|
||||||
onActionClick={() => this.handleOnCreateChatConversation(accountId)}
|
onActionClick={() => this.handleOnCreateChatConversation(accountId)}
|
||||||
actionIcon='add'
|
actionIcon='add'
|
||||||
@ -67,12 +75,15 @@ const mapStateToProps = (state) => ({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
onChange: (value) => {
|
onChange(value) {
|
||||||
dispatch(fetchChatConversationAccountSuggestions(value))
|
dispatch(fetchChatConversationAccountSuggestions(value))
|
||||||
},
|
},
|
||||||
onCreateChatConversation: (accountId) => {
|
onCreateChatConversation(accountId) {
|
||||||
dispatch(createChatConversation(accountId))
|
dispatch(createChatConversation(accountId))
|
||||||
},
|
},
|
||||||
|
onClearChatConversationAccountSuggestions() {
|
||||||
|
dispatch(clearChatConversationAccountSuggestions())
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
ChatConversationCreate.propTypes = {
|
ChatConversationCreate.propTypes = {
|
||||||
|
@ -30,10 +30,18 @@ class ComposeDestinationHeader extends ImmutablePureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { account, isModal, formLocation } = this.props
|
const {
|
||||||
|
account,
|
||||||
|
isModal,
|
||||||
|
composeGroup,
|
||||||
|
formLocation,
|
||||||
|
} = this.props
|
||||||
|
|
||||||
const isIntroduction = formLocation === 'introduction'
|
const isIntroduction = formLocation === 'introduction'
|
||||||
const title = 'Post to timeline'
|
|
||||||
|
let groupTitle = !!composeGroup ? composeGroup.get('title') : ''
|
||||||
|
groupTitle = groupTitle.length > 32 ? `${groupTitle.substring(0, 32).trim()}...` : groupTitle
|
||||||
|
const title = !!composeGroup ? `Post to ${groupTitle}` : 'Post to timeline'
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={[_s.d, _s.flexRow, _s.aiCenter, _s.bgPrimary, _s.w100PC, _s.h40PX, _s.pr15].join(' ')}>
|
<div className={[_s.d, _s.flexRow, _s.aiCenter, _s.bgPrimary, _s.w100PC, _s.h40PX, _s.pr15].join(' ')}>
|
||||||
@ -76,6 +84,15 @@ class ComposeDestinationHeader extends ImmutablePureComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = (state) => {
|
||||||
|
const composeGroupId = state.getIn(['compose', 'group_id'])
|
||||||
|
|
||||||
|
return {
|
||||||
|
composeGroupId,
|
||||||
|
composeGroup: state.getIn(['groups', composeGroupId]),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
onOpenModal() {
|
onOpenModal() {
|
||||||
dispatch(openModal(MODAL_COMPOSE))
|
dispatch(openModal(MODAL_COMPOSE))
|
||||||
@ -96,4 +113,4 @@ ComposeDestinationHeader.propTypes = {
|
|||||||
formLocation: PropTypes.string,
|
formLocation: PropTypes.string,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(null, mapDispatchToProps)(ComposeDestinationHeader)
|
export default connect(mapStateToProps, mapDispatchToProps)(ComposeDestinationHeader)
|
@ -134,6 +134,11 @@ class ComposeForm extends ImmutablePureComponent {
|
|||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
document.addEventListener('click', this.handleClick, false)
|
document.addEventListener('click', this.handleClick, false)
|
||||||
|
|
||||||
|
const { groupId } = this.props
|
||||||
|
if (groupId) {
|
||||||
|
this.props.onChangeComposeGroupId(groupId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
|
@ -12,6 +12,7 @@ import {
|
|||||||
changeComposeSpoilerText,
|
changeComposeSpoilerText,
|
||||||
uploadCompose,
|
uploadCompose,
|
||||||
changeScheduledAt,
|
changeScheduledAt,
|
||||||
|
changeComposeGroupId,
|
||||||
} from '../../../actions/compose'
|
} from '../../../actions/compose'
|
||||||
import { openModal } from '../../../actions/modal'
|
import { openModal } from '../../../actions/modal'
|
||||||
import { MODAL_COMPOSE } from '../../../constants'
|
import { MODAL_COMPOSE } from '../../../constants'
|
||||||
@ -132,6 +133,10 @@ const mapDispatchToProps = (dispatch, { isStandalone }) => ({
|
|||||||
openComposeModal() {
|
openComposeModal() {
|
||||||
dispatch(openModal(MODAL_COMPOSE))
|
dispatch(openModal(MODAL_COMPOSE))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onChangeComposeGroupId(groupId) {
|
||||||
|
dispatch(changeComposeGroupId(groupId))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
function mergeProps(stateProps, dispatchProps, ownProps) {
|
function mergeProps(stateProps, dispatchProps, ownProps) {
|
||||||
|
@ -73,9 +73,9 @@ class Deck extends React.PureComponent {
|
|||||||
getDeckColumn = (deckColumn, index) => {
|
getDeckColumn = (deckColumn, index) => {
|
||||||
if (!deckColumn || !this.props.isPro) return null
|
if (!deckColumn || !this.props.isPro) return null
|
||||||
|
|
||||||
let Component = null
|
let Component, noRefresh, accountId, icon = null
|
||||||
let componentParams = {}
|
let componentParams = {}
|
||||||
let title, subtitle, icon = ''
|
let title, subtitle = ''
|
||||||
|
|
||||||
switch (deckColumn) {
|
switch (deckColumn) {
|
||||||
case 'notifications':
|
case 'notifications':
|
||||||
@ -92,6 +92,7 @@ class Deck extends React.PureComponent {
|
|||||||
title = 'Compose'
|
title = 'Compose'
|
||||||
icon = 'pencil'
|
icon = 'pencil'
|
||||||
Component = Compose
|
Component = Compose
|
||||||
|
noRefresh = true
|
||||||
break
|
break
|
||||||
case 'likes':
|
case 'likes':
|
||||||
title = 'Likes'
|
title = 'Likes'
|
||||||
@ -127,7 +128,11 @@ class Deck extends React.PureComponent {
|
|||||||
|
|
||||||
if (!Component) {
|
if (!Component) {
|
||||||
if (deckColumn.indexOf('user.') > -1) {
|
if (deckColumn.indexOf('user.') > -1) {
|
||||||
|
const userAccountId = deckColumn.replace('user.', '')
|
||||||
|
title = 'User'
|
||||||
|
Component = AccountTimeline
|
||||||
|
componentParams = { id: userAccountId }
|
||||||
|
accountId = userAccountId
|
||||||
} else if (deckColumn.indexOf('list.') > -1) {
|
} else if (deckColumn.indexOf('list.') > -1) {
|
||||||
const listId = deckColumn.replace('list.', '')
|
const listId = deckColumn.replace('list.', '')
|
||||||
title = 'List'
|
title = 'List'
|
||||||
@ -162,7 +167,14 @@ class Deck extends React.PureComponent {
|
|||||||
index={index}
|
index={index}
|
||||||
sortIndex={index}
|
sortIndex={index}
|
||||||
>
|
>
|
||||||
<DeckColumn title={title} subtitle={subtitle} icon={icon} index={index}>
|
<DeckColumn
|
||||||
|
title={title}
|
||||||
|
subtitle={subtitle}
|
||||||
|
icon={icon}
|
||||||
|
index={index}
|
||||||
|
noRefresh={noRefresh}
|
||||||
|
accountId={accountId}
|
||||||
|
>
|
||||||
<WrappedBundle component={Component} componentParams={componentParams} />
|
<WrappedBundle component={Component} componentParams={componentParams} />
|
||||||
</DeckColumn>
|
</DeckColumn>
|
||||||
</SortableItem>
|
</SortableItem>
|
||||||
|
@ -182,9 +182,7 @@ class SlideFirstPost extends React.PureComponent {
|
|||||||
<Text size='large' className={_s.pb10}>Now let's make your very first Gab post! Please introduce yourself to the Gab community. How did you hear about Gab? What are you interested in?</Text>
|
<Text size='large' className={_s.pb10}>Now let's make your very first Gab post! Please introduce yourself to the Gab community. How did you hear about Gab? What are you interested in?</Text>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<Divider />
|
<div className={[_s.d, _s.boxShadowBlock, _s.overflowHidden, _s.radiusSmall].join(' ')}>
|
||||||
|
|
||||||
<div className={[_s.d, _s.mt15, _s.boxShadowBlock, _s.radiusSmall].join(' ')}>
|
|
||||||
<ComposeFormContainer
|
<ComposeFormContainer
|
||||||
formLocation='introduction'
|
formLocation='introduction'
|
||||||
groupId={GAB_COM_INTRODUCE_YOURSELF_GROUP_ID}
|
groupId={GAB_COM_INTRODUCE_YOURSELF_GROUP_ID}
|
||||||
|
@ -141,7 +141,9 @@ class ChatMessageItem extends ImmutablePureComponent {
|
|||||||
<div className={[_s.d, _s.w100PC, _s.pb15].join(' ')}>
|
<div className={[_s.d, _s.w100PC, _s.pb15].join(' ')}>
|
||||||
|
|
||||||
<div className={messageContainerClasses}>
|
<div className={messageContainerClasses}>
|
||||||
<Avatar account={chatMessage.get('account')} size={38} />
|
<NavLink to={`/${chatMessage.getIn(['account', 'username'])}`}>
|
||||||
|
<Avatar account={chatMessage.get('account')} size={38} />
|
||||||
|
</NavLink>
|
||||||
<div className={messageInnerContainerClasses}>
|
<div className={messageInnerContainerClasses}>
|
||||||
<div className={[_s.py5, _s.dangerousContent, _s.cPrimary].join(' ')} dangerouslySetInnerHTML={content} />
|
<div className={[_s.py5, _s.dangerousContent, _s.cPrimary].join(' ')} dangerouslySetInnerHTML={content} />
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,6 +6,7 @@ import {
|
|||||||
import { me } from '../initial_state'
|
import { me } from '../initial_state'
|
||||||
import {
|
import {
|
||||||
CHAT_CONVERSATION_CREATE_SEARCH_ACCOUNTS_SUCCESS,
|
CHAT_CONVERSATION_CREATE_SEARCH_ACCOUNTS_SUCCESS,
|
||||||
|
CLEAR_CHAT_CONVERSATION_CREATE_SEARCH_ACCOUNTS,
|
||||||
SET_CHAT_CONVERSATION_SELECTED,
|
SET_CHAT_CONVERSATION_SELECTED,
|
||||||
} from '../actions/chats'
|
} from '../actions/chats'
|
||||||
import {
|
import {
|
||||||
@ -29,6 +30,8 @@ export default function chats(state = initialState, action) {
|
|||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
case CHAT_CONVERSATION_CREATE_SEARCH_ACCOUNTS_SUCCESS:
|
case CHAT_CONVERSATION_CREATE_SEARCH_ACCOUNTS_SUCCESS:
|
||||||
return state.set('createChatConversationSuggestionIds', ImmutableList(action.accounts.map((item) => item.id)))
|
return state.set('createChatConversationSuggestionIds', ImmutableList(action.accounts.map((item) => item.id)))
|
||||||
|
case CLEAR_CHAT_CONVERSATION_CREATE_SEARCH_ACCOUNTS:
|
||||||
|
return state.set('createChatConversationSuggestionIds', ImmutableList())
|
||||||
case SET_CHAT_CONVERSATION_SELECTED:
|
case SET_CHAT_CONVERSATION_SELECTED:
|
||||||
return state.set('selectedChatConversationId', action.chatConversationId)
|
return state.set('selectedChatConversationId', action.chatConversationId)
|
||||||
case CHAT_CONVERSATION_REQUESTED_COUNT_FETCH_SUCCESS:
|
case CHAT_CONVERSATION_REQUESTED_COUNT_FETCH_SUCCESS:
|
||||||
|
@ -39,6 +39,7 @@ import {
|
|||||||
COMPOSE_EXPIRES_AT_CHANGE,
|
COMPOSE_EXPIRES_AT_CHANGE,
|
||||||
COMPOSE_RICH_TEXT_EDITOR_CONTROLS_VISIBILITY,
|
COMPOSE_RICH_TEXT_EDITOR_CONTROLS_VISIBILITY,
|
||||||
COMPOSE_CLEAR,
|
COMPOSE_CLEAR,
|
||||||
|
COMPOSE_GROUP_SET,
|
||||||
} from '../actions/compose';
|
} from '../actions/compose';
|
||||||
import { TIMELINE_DELETE } from '../actions/timelines';
|
import { TIMELINE_DELETE } from '../actions/timelines';
|
||||||
import { STORE_HYDRATE } from '../actions/store';
|
import { STORE_HYDRATE } from '../actions/store';
|
||||||
@ -62,6 +63,7 @@ const initialState = ImmutableMap({
|
|||||||
preselectDate: null,
|
preselectDate: null,
|
||||||
in_reply_to: null,
|
in_reply_to: null,
|
||||||
quote_of_id: null,
|
quote_of_id: null,
|
||||||
|
group_id: null,
|
||||||
is_composing: false,
|
is_composing: false,
|
||||||
is_submitting: false,
|
is_submitting: false,
|
||||||
is_changing_upload: false,
|
is_changing_upload: false,
|
||||||
@ -119,6 +121,7 @@ function clearAll(state) {
|
|||||||
map.set('expires_at', null);
|
map.set('expires_at', null);
|
||||||
map.set('rte_controls_visible', false);
|
map.set('rte_controls_visible', false);
|
||||||
map.set('gif', false);
|
map.set('gif', false);
|
||||||
|
map.set('group_id', null);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -305,6 +308,7 @@ export default function compose(state = initialState, action) {
|
|||||||
map.set('id', null);
|
map.set('id', null);
|
||||||
map.set('quote_of_id', null);
|
map.set('quote_of_id', null);
|
||||||
map.set('in_reply_to', null);
|
map.set('in_reply_to', null);
|
||||||
|
map.set('group_id', null);
|
||||||
map.set('text', '');
|
map.set('text', '');
|
||||||
map.set('spoiler', false);
|
map.set('spoiler', false);
|
||||||
map.set('spoiler_text', '');
|
map.set('spoiler_text', '');
|
||||||
@ -414,6 +418,8 @@ export default function compose(state = initialState, action) {
|
|||||||
return state.withMutations(map => {
|
return state.withMutations(map => {
|
||||||
map.set('rte_controls_visible', action.open || !state.get('rte_controls_visible'));
|
map.set('rte_controls_visible', action.open || !state.get('rte_controls_visible'));
|
||||||
});
|
});
|
||||||
|
case COMPOSE_GROUP_SET:
|
||||||
|
return state.set('group_id', action.groupId);
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,17 @@
|
|||||||
import {
|
import {
|
||||||
DECK_CONNECT,
|
DECK_CONNECT,
|
||||||
DECK_DISCONNECT,
|
DECK_DISCONNECT,
|
||||||
|
DECK_SEARCH_USERS_CLEAR,
|
||||||
|
DECK_SEARCH_USERS_SUCCESS,
|
||||||
} from '../actions/deck'
|
} from '../actions/deck'
|
||||||
import { Map as ImmutableMap } from 'immutable'
|
import {
|
||||||
|
Map as ImmutableMap,
|
||||||
|
List as ImmutableList,
|
||||||
|
} from 'immutable'
|
||||||
|
|
||||||
const initialState = ImmutableMap({
|
const initialState = ImmutableMap({
|
||||||
connected: false,
|
connected: false,
|
||||||
|
accountSuggestions: ImmutableList(),
|
||||||
})
|
})
|
||||||
|
|
||||||
export default function deck(state = initialState, action) {
|
export default function deck(state = initialState, action) {
|
||||||
@ -14,6 +20,10 @@ export default function deck(state = initialState, action) {
|
|||||||
return state.set('connected', true)
|
return state.set('connected', true)
|
||||||
case DECK_DISCONNECT:
|
case DECK_DISCONNECT:
|
||||||
return state.set('connected', false)
|
return state.set('connected', false)
|
||||||
|
case DECK_SEARCH_USERS_SUCCESS:
|
||||||
|
return state.set('accountSuggestions', ImmutableList(action.accounts.map((item) => item.id)))
|
||||||
|
case DECK_SEARCH_USERS_CLEAR:
|
||||||
|
return state.set('accountSuggestions', ImmutableList())
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user