diff --git a/package-lock.json b/package-lock.json
index bbf910c..99521af 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8625,6 +8625,29 @@
"minimist": "^1.2.0"
}
},
+ "jsonp": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/jsonp/-/jsonp-0.2.1.tgz",
+ "integrity": "sha1-pltPoPEL2nGaBUQep7lMVfPhW64=",
+ "requires": {
+ "debug": "^2.1.3"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
"jsonwebtoken": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
@@ -11756,6 +11779,17 @@
"tiny-warning": "^1.0.0"
}
},
+ "react-share": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/react-share/-/react-share-3.0.1.tgz",
+ "integrity": "sha512-xo4zjYP78h6zrBN5rlC06bb877js7216KFeZELAZP6sYxVoqmU27ChrfnpKUCL9H8F5PwYXh6DLNdAp+0E17GA==",
+ "requires": {
+ "babel-runtime": "^6.26.0",
+ "classnames": "^2.2.5",
+ "jsonp": "^0.2.1",
+ "prop-types": "^15.5.8"
+ }
+ },
"react-skeleton-loader": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/react-skeleton-loader/-/react-skeleton-loader-1.0.4.tgz",
diff --git a/package.json b/package.json
index 6166762..ff43a2e 100644
--- a/package.json
+++ b/package.json
@@ -66,6 +66,7 @@
"react-pusher": "^0.2.0",
"react-redux": "^7.1.1",
"react-router-dom": "^5.0.1",
+ "react-share": "^3.0.1",
"react-skeleton-loader": "^1.0.4",
"react-spinners": "^0.6.1",
"react-tag-input": "^6.4.1",
diff --git a/src/components/Icon/index.js b/src/components/Icon/index.js
index 21a2e17..73f3534 100644
--- a/src/components/Icon/index.js
+++ b/src/components/Icon/index.js
@@ -26,6 +26,7 @@ import {
faAngleLeft as angleLeft,
faAngleUp as angleTop,
faAngleDown as angleBottom,
+ faEllipsisH as options,
} from '@fortawesome/free-solid-svg-icons';
const icons = {
@@ -46,6 +47,7 @@ const icons = {
angleLeft,
angleTop,
angleBottom,
+ options,
};
const Icon = (props) => {
const { name, handleClick } = props;
diff --git a/src/e2e/Articles/ShareArticle.js b/src/e2e/Articles/ShareArticle.js
new file mode 100644
index 0000000..b260c9d
--- /dev/null
+++ b/src/e2e/Articles/ShareArticle.js
@@ -0,0 +1,33 @@
+module.exports = {
+ '@tag': ['articles'],
+ 'User should be able to share articles': (browser) => {
+ browser
+ .url('http://localhost:9090/articles/multi-byte-invoice-payment')
+ .pause(3000)
+ .assert.visible('div[class="read-article"]')
+ .pause(500)
+ .assert.visible('[class="option-icon dropdown"]')
+ .pause(1000)
+ .assert.visible('[data-icon="ellipsis-h"]')
+ .pause(200)
+ .moveToElement('[data-icon="ellipsis-h"]', 1, 1)
+ .pause(1000)
+ .moveToElement('[aria-label="email"]', 1, 1)
+ .pause(2000)
+ .moveToElement('[aria-label="twitter"]', 1, 1)
+ .pause(2000)
+ .moveToElement('[aria-label="facebook"]', 1, 1)
+ .pause(2000)
+ .moveToElement('[aria-label="email"]', 1, 1)
+ .pause(2000)
+ .moveToElement('[aria-label="twitter"]', 1, 1)
+ .pause(1000)
+ .assert.visible('[aria-label="twitter"]')
+ .assert.visible('[aria-label="facebook"]')
+ .assert.visible('[aria-label="email"]')
+ .pause(1000)
+ .click('[aria-label="twitter"]')
+ .pause(5000)
+ .end();
+ },
+};
diff --git a/src/views/Articles/ReadArticle/ReadArticle.js b/src/views/Articles/ReadArticle/ReadArticle.js
index 2d04036..5be6ed6 100644
--- a/src/views/Articles/ReadArticle/ReadArticle.js
+++ b/src/views/Articles/ReadArticle/ReadArticle.js
@@ -1,6 +1,8 @@
+/* eslint-disable jsx-a11y/interactive-supports-focus */
/* eslint-disable react/no-unused-prop-types */
/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
/* eslint-disable jsx-a11y/anchor-is-valid */
+/* eslint-disable jsx-a11y/interactive-supports-focus */
import React, { Component } from 'react';
import jwtDecode from 'jwt-decode';
import PropTypes from 'prop-types';
@@ -9,6 +11,14 @@ import ReactHtmlParser from 'react-html-parser';
import { withRouter, Link } from 'react-router-dom';
import swal from '@sweetalert/with-react';
import Loader from 'react-loader-spinner';
+import {
+ FacebookShareButton,
+ FacebookIcon,
+ TwitterShareButton,
+ TwitterIcon,
+ EmailShareButton,
+ EmailIcon,
+} from 'react-share';
import { readArticle, deleteAnArticle } from '@Actions/Articles';
import { getArticlesWithTagFromDb } from '@Actions/tagAction';
import { getProfile } from '@Actions/profileAction';
@@ -20,6 +30,7 @@ import { unFollowUser } from '@Actions/unfollowActions';
import { convertToHtml, isEmpty } from '@Utils/';
import './ReadArticle.scss';
+const appUrl = 'https://ah-commando-react.herokuapp.com';
export class ReadArticle extends Component {
state = {
errors: {},
@@ -139,6 +150,10 @@ export class ReadArticle extends Component {
});
}
+ handleClick = name => {
+ document.querySelector(`[aria-label="${name}"]`).click();
+ }
+
handleTagClick = async (tag) => {
const { getArticlesTag, history } = this.props;
await getArticlesTag(tag, history);
@@ -166,6 +181,9 @@ export class ReadArticle extends Component {
return history.push(`/profiles/${username}`);
};
+ handleClick = name => {
+ document.querySelector(`[aria-label="${name}"]`).click();
+ }
render = () => {
const {
@@ -183,6 +201,7 @@ export class ReadArticle extends Component {
dislikesCount,
comment,
id: articleId,
+ slug,
},
history,
auth: { isAuthenticated },
@@ -312,6 +331,43 @@ export class ReadArticle extends Component {
{' '}
+share on twitter
+ + this.handleClick('facebook')} + > +share on facebook
+ + this.handleClick('email')} + > +share by email
+ +