[New Feature] Add othe social network sharing buttons
This commit is contained in:
@@ -53,6 +53,7 @@
|
||||
"react-router-dom": "^4.1.1",
|
||||
"react-router-redux": "^5.0.0-alpha.6",
|
||||
"react-scripts-ts": "2.13.0",
|
||||
"react-share": "^2.0.0",
|
||||
"react-string-replace": "^0.4.0",
|
||||
"react-tap-event-plugin": "^3.0.2",
|
||||
"redux": "^3.7.2",
|
||||
|
||||
@@ -13,7 +13,6 @@ import { getTranslate, getActiveLanguage } from 'react-localize-redux'
|
||||
import { Card, CardActions, CardHeader, CardMedia, CardContent } from 'material-ui'
|
||||
import Typography from 'material-ui/Typography'
|
||||
import SvgShare from 'material-ui-icons/Share'
|
||||
import SvgLink from 'material-ui-icons/Link'
|
||||
import SvgComment from 'material-ui-icons/Comment'
|
||||
import SvgFavorite from 'material-ui-icons/Favorite'
|
||||
import SvgFavoriteBorder from 'material-ui-icons/FavoriteBorder'
|
||||
@@ -39,6 +38,7 @@ import reactStringReplace from 'react-string-replace'
|
||||
|
||||
// - Import app components
|
||||
import CommentGroup from 'components/commentGroup'
|
||||
import ShareDialog from 'components/shareDialog'
|
||||
import PostWrite from 'components/postWrite'
|
||||
import Img from 'components/img'
|
||||
import IconButtonElement from 'layouts/IconButtonElement'
|
||||
@@ -80,18 +80,6 @@ const styles = (theme: any) => ({
|
||||
pointerEvents: 'none',
|
||||
zIndex: 0
|
||||
},
|
||||
shareLinkPaper: {
|
||||
minHeight: 80,
|
||||
padding: 10,
|
||||
minWidth: 460
|
||||
},
|
||||
clipboard: {
|
||||
fontSize: '18px',
|
||||
textAlign: 'center',
|
||||
marginTop: '10px',
|
||||
color: '#1e882d',
|
||||
fontWeight: 400
|
||||
},
|
||||
postBody: {
|
||||
wordWrap: 'break-word',
|
||||
color: 'rgba(0, 0, 0, 0.87)',
|
||||
@@ -103,6 +91,14 @@ const styles = (theme: any) => ({
|
||||
image: {
|
||||
width: '100%',
|
||||
height: 500
|
||||
},
|
||||
fullPageXs: {
|
||||
[theme.breakpoints.down('xs')]: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
margin: 0,
|
||||
overflowY: 'auto'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -450,31 +446,15 @@ export class PostComponent extends Component<IPostComponentProps, IPostComponent
|
||||
|
||||
<CommentGroup open={this.state.openComments} comments={commentList} ownerPostUserId={post.ownerUserId!} onToggleRequest={this.handleOpenComments} isPostOwner={this.props.isPostOwner!} disableComments={post.disableComments!} postId={post.id!} />
|
||||
|
||||
{/* Copy link dialog*/}
|
||||
<Dialog
|
||||
title='Share On'
|
||||
open={this.state.shareOpen}
|
||||
onClose={this.handleCloseShare}
|
||||
>
|
||||
<Paper className={classes.shareLinkPaper}>
|
||||
{!this.state.openCopyLink
|
||||
? (<MenuList>
|
||||
<MenuItem onClick={this.handleCopyLink} >
|
||||
<ListItemIcon>
|
||||
<SvgLink />
|
||||
</ListItemIcon>
|
||||
<ListItemText inset primary={translate!('post.copyLinkButton')} />
|
||||
</MenuItem>
|
||||
</MenuList>)
|
||||
: <div>
|
||||
<TextField autoFocus fullWidth={true} id='text-field-default' defaultValue={`${location.origin}/${post.ownerUserId}/posts/${post.id}`} />
|
||||
<Typography className={classNames('animate-top', classes.clipboard)} variant='headline' component='h2'>
|
||||
Link has been copied to clipboard ...
|
||||
</Typography>
|
||||
</div>}
|
||||
</Paper>
|
||||
</Dialog>
|
||||
<ShareDialog
|
||||
onClose={this.handleCloseShare}
|
||||
shareOpen={this.state.shareOpen}
|
||||
onCopyLink={this.handleCopyLink}
|
||||
openCopyLink={this.state.openCopyLink}
|
||||
post={post}
|
||||
|
||||
/>
|
||||
|
||||
<PostWrite
|
||||
open={this.state.openPostWrite}
|
||||
onRequestClose={this.handleClosePostWrite}
|
||||
|
||||
40
src/components/shareDialog/IShareDialogComponentProps.ts
Normal file
40
src/components/shareDialog/IShareDialogComponentProps.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { Post } from 'core/domain/posts'
|
||||
|
||||
export interface IShareDialogComponentProps {
|
||||
|
||||
/**
|
||||
* Whether share dialog is open
|
||||
*/
|
||||
shareOpen: boolean
|
||||
|
||||
/**
|
||||
* On close share dialog
|
||||
*/
|
||||
onClose: () => void
|
||||
|
||||
/**
|
||||
* Whether copy link is displayed
|
||||
*/
|
||||
openCopyLink: boolean
|
||||
|
||||
/**
|
||||
* On copy link
|
||||
*/
|
||||
onCopyLink: () => void
|
||||
|
||||
/**
|
||||
* The post object for sharing
|
||||
*/
|
||||
post: Post
|
||||
|
||||
/**
|
||||
* Styles
|
||||
*/
|
||||
classes?: any
|
||||
|
||||
/**
|
||||
* Translate to locale string
|
||||
*/
|
||||
translate?: (state: any) => any
|
||||
|
||||
}
|
||||
4
src/components/shareDialog/IShareDialogComponentState.ts
Normal file
4
src/components/shareDialog/IShareDialogComponentState.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
export interface IShareDialogComponentState {
|
||||
|
||||
}
|
||||
213
src/components/shareDialog/ShareDialogComponent.tsx
Normal file
213
src/components/shareDialog/ShareDialogComponent.tsx
Normal file
@@ -0,0 +1,213 @@
|
||||
// - Import react components
|
||||
import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { connect } from 'react-redux'
|
||||
import SvgImage from 'material-ui-icons/Image'
|
||||
import { withStyles } from 'material-ui/styles'
|
||||
import { getTranslate, getActiveLanguage } from 'react-localize-redux'
|
||||
import classNames from 'classnames'
|
||||
|
||||
import {
|
||||
FacebookShareButton,
|
||||
FacebookIcon,
|
||||
|
||||
TwitterShareButton,
|
||||
TwitterIcon,
|
||||
|
||||
GooglePlusShareButton,
|
||||
GooglePlusIcon,
|
||||
|
||||
LinkedinShareButton,
|
||||
LinkedinIcon
|
||||
} from 'react-share'
|
||||
|
||||
// - Import app components
|
||||
|
||||
// - Import API
|
||||
|
||||
// - Import actions
|
||||
import { IShareDialogComponentProps } from './IShareDialogComponentProps'
|
||||
import { IShareDialogComponentState } from './IShareDialogComponentState'
|
||||
import { Dialog, Paper, MenuList, MenuItem, ListItemIcon, ListItemText, TextField, Typography } from 'material-ui'
|
||||
import SvgLink from 'material-ui-icons/Link'
|
||||
|
||||
const styles = (theme: any) => ({
|
||||
image: {
|
||||
verticalAlign: 'top',
|
||||
maxWidth: '100%',
|
||||
minWidth: '100%',
|
||||
width: '100%'
|
||||
},
|
||||
clipboard: {
|
||||
fontSize: '18px',
|
||||
textAlign: 'center',
|
||||
marginTop: '10px',
|
||||
color: '#1e882d',
|
||||
fontWeight: 400
|
||||
},
|
||||
networkShare: {
|
||||
width: '100%',
|
||||
height: '100%'
|
||||
},
|
||||
fullPageXs: {
|
||||
[theme.breakpoints.down('xs')]: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
margin: 0,
|
||||
overflowY: 'auto'
|
||||
}
|
||||
},
|
||||
shareLinkPaper: {
|
||||
minHeight: 80,
|
||||
padding: 10,
|
||||
minWidth: 460
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* Create component class
|
||||
*/
|
||||
export class ShareDialogComponent extends Component<IShareDialogComponentProps, IShareDialogComponentState> {
|
||||
|
||||
/**
|
||||
* Component constructor
|
||||
* @param {object} props is an object properties of component
|
||||
*/
|
||||
constructor(props: IShareDialogComponentProps) {
|
||||
super(props)
|
||||
|
||||
// Defaul state
|
||||
this.state = {
|
||||
|
||||
}
|
||||
|
||||
// Binding functions to `this`
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reneder component DOM
|
||||
* @return {react element} return the DOM which rendered by component
|
||||
*/
|
||||
render() {
|
||||
|
||||
let { classes, translate, shareOpen, onClose, openCopyLink, post, onCopyLink } = this.props
|
||||
return (
|
||||
<Dialog
|
||||
className={classes.fullPageXs}
|
||||
title='Share On'
|
||||
open={shareOpen}
|
||||
onClose={onClose}
|
||||
>
|
||||
<Paper className={classes.shareLinkPaper}>
|
||||
{!openCopyLink
|
||||
? (<MenuList>
|
||||
<div>
|
||||
<FacebookShareButton
|
||||
onShareWindowClose={onClose}
|
||||
url={`https://test-4515a.firebaseapp.com/${post.ownerUserId}/posts/${post.id}`}
|
||||
quote={post.body}
|
||||
hashtag={`#${post.tags![0]}`}>
|
||||
<MenuItem >
|
||||
<ListItemIcon classes={{ root: classes.networkShare }}>
|
||||
<FacebookIcon
|
||||
size={32}
|
||||
round />
|
||||
</ListItemIcon>
|
||||
<ListItemText inset primary={translate!('post.facebookButton')} />
|
||||
</MenuItem>
|
||||
</FacebookShareButton>
|
||||
</div>
|
||||
<div>
|
||||
<TwitterShareButton
|
||||
onShareWindowClose={onClose}
|
||||
url={`https://test-4515a.firebaseapp.com/${post.ownerUserId}/posts/${post.id}`}
|
||||
quote={post.body}
|
||||
hashtag={`#${post.tags![0]}`}>
|
||||
<MenuItem >
|
||||
<ListItemIcon classes={{ root: classes.networkShare }}>
|
||||
<TwitterIcon
|
||||
size={32}
|
||||
round />
|
||||
</ListItemIcon>
|
||||
<ListItemText inset primary={translate!('post.twitterButton')} />
|
||||
</MenuItem>
|
||||
</TwitterShareButton>
|
||||
</div>
|
||||
<div>
|
||||
<LinkedinShareButton
|
||||
onShareWindowClose={onClose}
|
||||
url={`https://test-4515a.firebaseapp.com/${post.ownerUserId}/posts/${post.id}`}
|
||||
quote={post.body}
|
||||
hashtag={`#${post.tags![0]}`}>
|
||||
<MenuItem >
|
||||
<ListItemIcon classes={{ root: classes.networkShare }}>
|
||||
<LinkedinIcon
|
||||
size={32}
|
||||
round />
|
||||
</ListItemIcon>
|
||||
<ListItemText inset primary={translate!('post.linkedinButton')} />
|
||||
</MenuItem>
|
||||
</LinkedinShareButton>
|
||||
</div>
|
||||
<div>
|
||||
<GooglePlusShareButton
|
||||
onShareWindowClose={onClose}
|
||||
url={`https://test-4515a.firebaseapp.com/${post.ownerUserId}/posts/${post.id}`}
|
||||
quote={post.body}
|
||||
hashtag={`#${post.tags![0]}`}>
|
||||
<MenuItem >
|
||||
<ListItemIcon classes={{ root: classes.networkShare }}>
|
||||
<GooglePlusIcon
|
||||
size={32}
|
||||
round />
|
||||
</ListItemIcon>
|
||||
<ListItemText inset primary={translate!('post.googlePlusButton')} />
|
||||
</MenuItem>
|
||||
</GooglePlusShareButton>
|
||||
</div>
|
||||
<MenuItem onClick={onCopyLink} >
|
||||
<ListItemIcon>
|
||||
<SvgLink />
|
||||
</ListItemIcon>
|
||||
<ListItemText inset primary={translate!('post.copyLinkButton')} />
|
||||
</MenuItem>
|
||||
</MenuList>)
|
||||
: <div>
|
||||
<TextField autoFocus fullWidth={true} id='text-field-default' defaultValue={`${location.origin}/${post.ownerUserId}/posts/${post.id}`} />
|
||||
<Typography className={classNames('animate-top', classes.clipboard)} variant='headline' component='h2'>
|
||||
Link has been copied to clipboard ...
|
||||
</Typography>
|
||||
</div>}
|
||||
</Paper>
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Map dispatch to props
|
||||
* @param {func} dispatch is the function to dispatch action to reducers
|
||||
* @param {object} ownProps is the props belong to component
|
||||
* @return {object} props of component
|
||||
*/
|
||||
const mapDispatchToProps = (dispatch: any, ownProps: IShareDialogComponentProps) => {
|
||||
return {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Map state to props
|
||||
* @param {object} state is the obeject from redux store
|
||||
* @param {object} ownProps is the props belong to component
|
||||
* @return {object} props of component
|
||||
*/
|
||||
const mapStateToProps = (state: any, ownProps: IShareDialogComponentProps) => {
|
||||
return {
|
||||
translate: getTranslate(state.locale)
|
||||
}
|
||||
}
|
||||
|
||||
// - Connect component to redux store
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles as any)(ShareDialogComponent as any) as any)
|
||||
2
src/components/shareDialog/index.ts
Normal file
2
src/components/shareDialog/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
import ShareDialogComponent from './ShareDialogComponent'
|
||||
export default ShareDialogComponent
|
||||
@@ -30,7 +30,11 @@
|
||||
"postButton": "POST",
|
||||
"cancelButton": "CANCEL",
|
||||
"updateButton": "UPDATE",
|
||||
"copyLinkButton": "Copy Link"
|
||||
"copyLinkButton": "Copy Link",
|
||||
"facebookButton": "Share in Facebook",
|
||||
"twitterButton": "Share in Twitter",
|
||||
"linkedinButton": "Share in Linkedin",
|
||||
"googlePlusButton": "Share in Google+"
|
||||
|
||||
},
|
||||
"imageGallery": {
|
||||
|
||||
1
src/typings/react-share.ts
Normal file
1
src/typings/react-share.ts
Normal file
@@ -0,0 +1 @@
|
||||
declare module 'react-share'
|
||||
19
yarn.lock
19
yarn.lock
@@ -691,7 +691,7 @@ babel-register@^6.26.0:
|
||||
mkdirp "^0.5.1"
|
||||
source-map-support "^0.4.15"
|
||||
|
||||
babel-runtime@^6.22.0, babel-runtime@^6.26.0:
|
||||
babel-runtime@^6.22.0, babel-runtime@^6.26.0, babel-runtime@^6.6.1:
|
||||
version "6.26.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
|
||||
dependencies:
|
||||
@@ -1659,7 +1659,7 @@ date-now@^0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b"
|
||||
|
||||
debug@2, debug@2.6.9, debug@^2.2.0, debug@^2.6.0, debug@^2.6.6, debug@^2.6.8:
|
||||
debug@2, debug@2.6.9, debug@^2.1.3, debug@^2.2.0, debug@^2.6.0, debug@^2.6.6, debug@^2.6.8:
|
||||
version "2.6.9"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||
dependencies:
|
||||
@@ -3978,6 +3978,12 @@ jsonify@~0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
|
||||
|
||||
jsonp@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/jsonp/-/jsonp-0.2.1.tgz#a65b4fa0f10bda719a05441ea7b94c55f3e15bae"
|
||||
dependencies:
|
||||
debug "^2.1.3"
|
||||
|
||||
jsonparse@^1.2.0:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280"
|
||||
@@ -6249,6 +6255,15 @@ react-scrollbar-size@^2.0.2:
|
||||
react-event-listener "^0.5.1"
|
||||
stifle "^1.0.2"
|
||||
|
||||
react-share@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/react-share/-/react-share-2.0.0.tgz#be07224dfe01ea0613e84e9412dddf0a1ed07a20"
|
||||
dependencies:
|
||||
babel-runtime "^6.6.1"
|
||||
classnames "^2.2.5"
|
||||
jsonp "^0.2.1"
|
||||
prop-types "^15.5.8"
|
||||
|
||||
react-string-replace@^0.4.0:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/react-string-replace/-/react-string-replace-0.4.1.tgz#024c6ac0a91163ecae439a1b197d3e1660c98c0d"
|
||||
|
||||
Reference in New Issue
Block a user