at the end of the day, it was inevitable
This commit is contained in:
+90
@@ -0,0 +1,90 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { translate } from 'react-i18next'
|
||||
import ClipDragSource from './ClipDragSource'
|
||||
import RecentFeed from './RecentFeed'
|
||||
import { Button, Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap'
|
||||
|
||||
export class ClipArticlesPopup extends React.Component {
|
||||
static propTypes = {
|
||||
hidePopup: PropTypes.func.isRequired,
|
||||
clipArticles: PropTypes.func.isRequired,
|
||||
articles: PropTypes.array.isRequired,
|
||||
recentClipFeeds: PropTypes.array.isRequired,
|
||||
getRecentClipFeeds: PropTypes.func.isRequired,
|
||||
t: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
hidePopupFromOutside = (e) => {
|
||||
if (e.target === e.currentTarget) this.hidePopup()
|
||||
}
|
||||
|
||||
hidePopup = () => {
|
||||
this.props.hidePopup()
|
||||
}
|
||||
|
||||
onSubmit = () => {
|
||||
this.hidePopup()
|
||||
}
|
||||
|
||||
componentWillMount = () => {
|
||||
this.props.getRecentClipFeeds()
|
||||
}
|
||||
|
||||
onRecentFeedClick = (feed) => {
|
||||
this.props.clipArticles(feed.id)
|
||||
this.props.hidePopup()
|
||||
}
|
||||
|
||||
render() {
|
||||
const { t, articles, recentClipFeeds } = this.props
|
||||
|
||||
return (
|
||||
<Modal
|
||||
isOpen
|
||||
toggle={this.hidePopup}
|
||||
backdrop={false}
|
||||
modalClassName="pointer-events-none"
|
||||
>
|
||||
<ModalHeader toggle={this.hidePopup}>
|
||||
{t('searchTab.clipPopup.header')}
|
||||
</ModalHeader>
|
||||
<ModalBody>
|
||||
<div className="text-center">
|
||||
<p>{t('searchTab.clipPopup.hint1')}</p>
|
||||
|
||||
<div className="draggable-container">
|
||||
<ClipDragSource articles={articles} />
|
||||
</div>
|
||||
|
||||
{recentClipFeeds && recentClipFeeds.length > 0 && (
|
||||
<div className="mt-2">
|
||||
<p className="mb-2">{t('searchTab.clipPopup.hint2')}</p>
|
||||
<div className="d-flex justify-content-center flex-wrap">
|
||||
{recentClipFeeds.map((feed) => {
|
||||
return (
|
||||
<RecentFeed
|
||||
onRecentFeedClick={this.onRecentFeedClick}
|
||||
key={feed.id}
|
||||
feed={feed}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button color="light" onClick={this.hidePopup}>
|
||||
{t('common:commonWords.Cancel')}
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default translate(['tabsContent', 'common'], { wait: true })(
|
||||
ClipArticlesPopup
|
||||
)
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { TYPES } from '../../../../../../redux/modules/appState/sidebar'
|
||||
import { Interpolate } from 'react-i18next'
|
||||
import { DragSource } from 'react-dnd'
|
||||
|
||||
const source = {
|
||||
beginDrag (props, monitor, component) {
|
||||
setTimeout(() => {
|
||||
component.setState({
|
||||
isDragging: true
|
||||
})
|
||||
}, 0)
|
||||
return {
|
||||
type: TYPES.CLIP_ARTICLE
|
||||
}
|
||||
},
|
||||
|
||||
endDrag (props, monitor, component) {
|
||||
component.setState({
|
||||
isDragging: false
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies which props to inject into component from Drag n Drop.
|
||||
*/
|
||||
function collect (connect) {
|
||||
return {
|
||||
// Call this function inside render()
|
||||
// to let React DnD handle the drag events:
|
||||
connectDragSource: connect.dragSource()
|
||||
}
|
||||
}
|
||||
|
||||
export class ClipDragSource extends React.Component {
|
||||
|
||||
static propTypes = {
|
||||
articles: PropTypes.array.isRequired,
|
||||
connectDragSource: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
constructor (props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
isDragging: false
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
|
||||
const style = {
|
||||
visibility: this.state.isDragging ? 'hidden' : 'visible'
|
||||
}
|
||||
|
||||
return this.props.connectDragSource(
|
||||
<div className="draggable-item" style={style}>
|
||||
<span className="drag-handle" />
|
||||
<Interpolate
|
||||
i18nKey='searchTab.clipPopup.clippedArticles'
|
||||
count={this.props.articles.length}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default DragSource(TYPES.CLIP_ARTICLE, source, collect)(ClipDragSource)
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Button } from 'reactstrap'
|
||||
|
||||
export default class RecentFeed extends React.Component {
|
||||
|
||||
static propTypes = {
|
||||
feed: PropTypes.object.isRequired,
|
||||
onRecentFeedClick: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
onClick = () => {
|
||||
this.props.onRecentFeedClick(this.props.feed)
|
||||
}
|
||||
|
||||
render () {
|
||||
const { feed } = this.props
|
||||
|
||||
return (
|
||||
<Button color="light" className={'mr-2 mb-2 feed-icon ' + feed.class} onClick={this.onClick}>
|
||||
{feed.name}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user