gatsby-matrix-theme 3.0.10 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/package.json +2 -2
  3. package/src/components/atoms/cards/operators-table/index.js +58 -0
  4. package/src/components/atoms/cards/operators-table/table.module.scss +87 -0
  5. package/src/gatsby-core-theme/components/atoms/spotlights/spotlights.module.scss +1 -0
  6. package/src/gatsby-core-theme/components/molecules/footer/index.js +5 -7
  7. package/src/gatsby-core-theme/components/molecules/module/index.js +4 -0
  8. package/src/gatsby-core-theme/components/organisms/carousel/carousel.module.scss +26 -2
  9. package/src/gatsby-core-theme/components/organisms/head/index.js +48 -33
  10. package/src/gatsby-core-theme/styles/utils/variables/_main.scss +10 -0
  11. package/src/helpers/strings.js +40 -29
  12. package/storybook/public/{0.3d8cbeeb.iframe.bundle.js → 0.741e5022.iframe.bundle.js} +1 -1
  13. package/storybook/public/{1.d529c1ee.iframe.bundle.js → 1.d02d8599.iframe.bundle.js} +1 -1
  14. package/storybook/public/{10.cea4ee5b.iframe.bundle.js → 10.ddb198cb.iframe.bundle.js} +1 -1
  15. package/storybook/public/{11.754b00b3.iframe.bundle.js → 11.86382beb.iframe.bundle.js} +1 -1
  16. package/storybook/public/{12.8a1881b8.iframe.bundle.js → 12.b6909189.iframe.bundle.js} +1 -1
  17. package/storybook/public/{13.38f19c6d.iframe.bundle.js → 13.9e6703fb.iframe.bundle.js} +1 -1
  18. package/storybook/public/{14.40f89dec.iframe.bundle.js → 14.b0c67bdf.iframe.bundle.js} +1 -1
  19. package/storybook/public/{15.ff9ffc19.iframe.bundle.js → 15.7bb7d301.iframe.bundle.js} +1 -1
  20. package/storybook/public/{16.dc8af8aa.iframe.bundle.js → 16.d64c7fd7.iframe.bundle.js} +1 -1
  21. package/storybook/public/{5.2ab0bd17.iframe.bundle.js → 5.80aa479a.iframe.bundle.js} +3 -3
  22. package/storybook/public/{5.2ab0bd17.iframe.bundle.js.LICENSE.txt → 5.80aa479a.iframe.bundle.js.LICENSE.txt} +0 -0
  23. package/storybook/public/5.80aa479a.iframe.bundle.js.map +1 -0
  24. package/storybook/public/{6.c5ba0afd.iframe.bundle.js → 6.ed0e7e34.iframe.bundle.js} +1 -1
  25. package/storybook/public/7.906eebeb.iframe.bundle.js +1 -0
  26. package/storybook/public/{8.e3bb3545.iframe.bundle.js → 8.c5053ebc.iframe.bundle.js} +1 -1
  27. package/storybook/public/{9.a7474f26.iframe.bundle.js → 9.05a986eb.iframe.bundle.js} +3 -3
  28. package/storybook/public/{9.a7474f26.iframe.bundle.js.LICENSE.txt → 9.05a986eb.iframe.bundle.js.LICENSE.txt} +0 -0
  29. package/storybook/public/9.05a986eb.iframe.bundle.js.map +1 -0
  30. package/storybook/public/iframe.html +1 -1
  31. package/storybook/public/main.074d0b0b.iframe.bundle.js +1 -0
  32. package/storybook/public/{runtime~main.e42f049a.iframe.bundle.js → runtime~main.d48e48c3.iframe.bundle.js} +1 -1
  33. package/storybook/public/vendors~main.fcfe1398.iframe.bundle.js +7 -0
  34. package/storybook/public/{vendors~main.fce7a779.iframe.bundle.js.LICENSE.txt → vendors~main.fcfe1398.iframe.bundle.js.LICENSE.txt} +0 -0
  35. package/storybook/public/vendors~main.fcfe1398.iframe.bundle.js.map +1 -0
  36. package/storybook/public/5.2ab0bd17.iframe.bundle.js.map +0 -1
  37. package/storybook/public/7.3af39400.iframe.bundle.js +0 -1
  38. package/storybook/public/9.a7474f26.iframe.bundle.js.map +0 -1
  39. package/storybook/public/main.94d6f05d.iframe.bundle.js +0 -1
  40. package/storybook/public/vendors~main.fce7a779.iframe.bundle.js +0 -7
  41. package/storybook/public/vendors~main.fce7a779.iframe.bundle.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,3 +1,39 @@
1
+ # [3.1.0](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/compare/v3.0.10...v3.1.0) (2021-12-17)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * add default copyright_disclaimer ([f0c330f](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/commit/f0c330fc779e79be0e6a7bab17cd54989e3e93de))
7
+ * carousel slides ([ae7dea9](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/commit/ae7dea9a0025daca522572efbd6ce27b5c7d3a0a))
8
+ * casino table ([2d0b8ec](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/commit/2d0b8ec4cd2e18fc9a21d1b17dcf1c529ac03aab))
9
+ * fixed bonus issue and loadable condition ([7f1f1a7](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/commit/7f1f1a7d6e467da005b60a8806056280fad671e7))
10
+ * fixed copyrightDisclaimer ([1a606d2](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/commit/1a606d2990c3883e2a3f0541d369e52dd93457f4))
11
+ * merge ([14a32ab](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/commit/14a32ab72c7c430e3619755433d5a92a79fe742c))
12
+ * merged master ([5a983ab](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/commit/5a983ab64013fe9029d99eea3223ecb2c4145a1b))
13
+ * progress made ([55c3175](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/commit/55c3175b5e827a2d1c3d1b33cb44ff3ca3b23379))
14
+ * remove re-declared copyrightDisclaimer ([598ac18](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/commit/598ac182d54e7a62e638ccfe42cda809f899ffc7))
15
+ * small fix ([9d8c24d](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/commit/9d8c24dc18245c6b07c658afce398ddf55802cec))
16
+ * small fix ([a9341ad](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/commit/a9341ad547865d2a154c98d55d12c78bd09f5982))
17
+ * spotlight images ([8daaf46](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/commit/8daaf460f49bafdda908899ae37fe8ff992befe2))
18
+ * spotlight images ([fa886b6](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/commit/fa886b6cbe2aa31992a415828f21f2927d5d8c97))
19
+ * style issues ([2881939](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/commit/28819392bbfec1ffa64739b42cb9dfc367ef7f82))
20
+ * updated core theme version and fixed disclaimer text bug ([3ce75e2](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/commit/3ce75e2c58812fef1ee3177c200a5268a5763f78))
21
+
22
+
23
+ ### Code Refactoring
24
+
25
+ * check the data ([dd25ece](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/commit/dd25ece863cd5956663ab47a34dde6eca5ded85a))
26
+
27
+
28
+ * Merge branch 'tm-2613-carousel-fix' into 'master' ([bdf02e8](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/commit/bdf02e8b330e9923437ae8a1c68568ce19c2c181))
29
+ * Merge branch 'tm-2597-casino-table' into 'master' ([6861c37](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/commit/6861c37c160aab7426288b8b4f40b3b8eabad3cf))
30
+ * Update index.js ([056c9bd](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/commit/056c9bddb0d7e63d0fbe8538968933c4d69d99b8))
31
+
32
+
33
+ ### Features
34
+
35
+ * twitter graph ([dfdf8bf](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/commit/dfdf8bfe5e9ff07a20b25f2c5f659126767dcffb))
36
+
1
37
  ## [3.0.10](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/compare/v3.0.9...v3.0.10) (2021-12-10)
2
38
 
3
39
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gatsby-matrix-theme",
3
- "version": "3.0.10",
3
+ "version": "3.1.0",
4
4
  "main": "index.js",
5
5
  "description": "Matrix Theme NPM Package",
6
6
  "author": "",
@@ -31,7 +31,7 @@
31
31
  "cross-env": "^7.0.2",
32
32
  "dotenv": "8.2.0",
33
33
  "gatsby": "^3.3.1",
34
- "gatsby-core-theme": "^1.6.22",
34
+ "gatsby-core-theme": "^2.0.1",
35
35
  "gatsby-image": "^3.3.0",
36
36
  "gatsby-plugin-image": "^1.3.1",
37
37
  "gatsby-plugin-postcss": "^4.3.0",
@@ -0,0 +1,58 @@
1
+ /* eslint-disable camelcase */
2
+ import React, { useContext } from 'react';
3
+ import PropTypes from 'prop-types';
4
+ import Link from 'gatsby-core-theme/src/hooks/link';
5
+ import { Context } from 'gatsby-core-theme/src/context/TranslationsProvider';
6
+ import { translate, getBonus } from 'gatsby-core-theme/src/helpers/getters';
7
+ import styles from './table.module.scss';
8
+
9
+ const CasinosTable = ({ module }) => {
10
+ const { translations } = useContext(Context);
11
+ const { items } = module || {};
12
+
13
+ const oneLiner = ({ one_liner }) => {
14
+ const [firstLine, secondLine] = one_liner.split('+');
15
+ return (
16
+ <>
17
+ <span className={styles.firstLine}>{firstLine}<br /></span>
18
+ <span className={styles.secondLine}>{`+${secondLine}`}</span>
19
+ </>
20
+ );
21
+ };
22
+
23
+ return (
24
+ <div className={styles.container}>
25
+ <table>
26
+ <thead>
27
+ <tr>
28
+ <th>{`${translate(translations, 'casino', 'Casino')}`}</th>
29
+ <th>{`${translate(translations, 'bonus', 'Bonus')}`}</th>
30
+ <th>{`${translate(translations, 'visit_casino', 'Visit casino')}`}</th>
31
+ </tr>
32
+ </thead>
33
+ <tbody>
34
+ {items &&
35
+ items.map((item) => (
36
+ <tr>
37
+ <td>{item.title}</td>
38
+ <td>{oneLiner(getBonus('main', item?.relation))}</td>
39
+ <td>
40
+ <Link to={item?.path} name={item?.relation?.name}>
41
+ {`${item?.relation?.name} ${translate(translations, 'read_review', 'Review')}`}
42
+ </Link>
43
+ </td>
44
+ </tr>
45
+ ))}
46
+ </tbody>
47
+ </table>
48
+ </div>
49
+ );
50
+ };
51
+
52
+ export default CasinosTable;
53
+
54
+ CasinosTable.propTypes = {
55
+ module: PropTypes.shape({
56
+ items: PropTypes.arrayOf({}),
57
+ }).isRequired,
58
+ };
@@ -0,0 +1,87 @@
1
+ .container {
2
+ table {
3
+ width: 100%;
4
+ border-collapse: inherit;
5
+ box-shadow: 0 2px 16px #17182f14;
6
+ thead {
7
+ tr {
8
+ th {
9
+ text-align: left;
10
+ background-color: var(--table-head-background);
11
+ color: white;
12
+ padding: 1.2rem 0 1.2rem 0.8rem;
13
+ &:first-child {
14
+ border-top-left-radius: var(--table-border-radius);
15
+ }
16
+
17
+ &:last-child {
18
+ border-top-right-radius: var(--table-border-radius);
19
+ }
20
+ }
21
+ }
22
+ }
23
+ tr {
24
+ td {
25
+ padding: 1.2rem 0 1.2rem 0.8rem;
26
+ a {
27
+ text-decoration: underline;
28
+ }
29
+ .secondLine{
30
+ color: red;
31
+ }
32
+ }
33
+ &:nth-child(odd) {
34
+ background-color: var(--table-highlight);
35
+ }
36
+ }
37
+
38
+ @include max(mobile) {
39
+ thead {
40
+ display: none;
41
+ }
42
+
43
+ tbody {
44
+ tr {
45
+ &:first-child {
46
+
47
+ td {
48
+ color: white;
49
+ background-color: var(--table-head-background);
50
+ border-radius: 0;
51
+ .secondLine{
52
+ color: white;
53
+ }
54
+ &:first-child {
55
+ border-top-left-radius: var(--table-border-radius);
56
+ border-top-right-radius: var(--table-border-radius);
57
+ }
58
+
59
+ a {
60
+ color: white;
61
+ text-decoration: underline;
62
+ }
63
+ }
64
+ }
65
+
66
+ td {
67
+ display: block;
68
+ text-align: left;
69
+ border-bottom: 1px solid #bfd3e5;
70
+ width: 100%;
71
+ }
72
+
73
+ &:last-child {
74
+ td {
75
+ border-radius: 0;
76
+ &:last-child {
77
+ border-bottom-right-radius: var(--table-border-radius);
78
+ border-bottom-left-radius: var(--table-border-radius);
79
+ border-bottom: none;
80
+ }
81
+ }
82
+ }
83
+ }
84
+ }
85
+ }
86
+ }
87
+ }
@@ -42,6 +42,7 @@
42
42
  width: 100%;
43
43
  img {
44
44
  height: 5.6rem;
45
+ width: auto;
45
46
  }
46
47
  }
47
48
  .label {
@@ -19,6 +19,7 @@ const Footer = ({
19
19
  const TopSection = footerTopCustom;
20
20
  const BottomSection = footerBottomCustom;
21
21
  const showLinks = template !== 'ppc';
22
+ const copyrightDisclaimerValue = getExtraField(section?.extra_fields, copyrightDisclaimer);
22
23
 
23
24
  return (
24
25
  <footer className={`${styles.footer} ${hasFooterLinks && styles.hasFooterLinks}`}>
@@ -38,20 +39,17 @@ const Footer = ({
38
39
  <div className={styles.bottomPart}>
39
40
  {footerBottomCustom && <BottomSection section={section} page={page} />}
40
41
  <div className={styles.copyrightDisclaimer}>
41
- {copyrightDisclaimer && getExtraField(section?.extra_fields, copyrightDisclaimer) && (
42
- <p
42
+ {copyrightDisclaimerValue && (
43
+ <div
43
44
  dangerouslySetInnerHTML={{
44
- __html: getExtraField(section?.extra_fields, copyrightDisclaimer).replace(
45
- /\. /g,
46
- '.<br />'
47
- ),
45
+ __html: copyrightDisclaimerValue.replace(/\. /g, '.<br />'),
48
46
  }}
49
47
  />
50
48
  )}
51
49
  <p>{copyrightText()}</p>
52
50
  </div>
53
51
  <div className={styles.logos}>
54
- {footerLogos && (
52
+ {footerLogos && getExtraField(section?.extra_fields, footerLogos) && (
55
53
  <LinkList
56
54
  showListTitle={false}
57
55
  imageOnly
@@ -22,7 +22,11 @@ const Modules = ({ module, page, pageContext }) => {
22
22
  case 'counter':
23
23
  return loadable(() => import('gatsby-core-theme/src/components/molecules/counter'));
24
24
  case 'cards':
25
+ return loadable(() => import('../../organisms/cards'));
25
26
  case 'cards_v2':
27
+ if (moduleItem.style === 'stack_table' && moduleItem.cards_page_type === 'operator') {
28
+ return loadable(() => import('../../../../components/atoms/cards/operators-table'));
29
+ }
26
30
  return loadable(() => import('../../organisms/cards'));
27
31
  case 'pros_and_cons':
28
32
  return loadable(() => import('gatsby-core-theme/src/components/molecules/pros-cons'));
@@ -1,3 +1,27 @@
1
- .screenshotCarousel > div {
2
- outline: none;
1
+ :global {
2
+ .carousel-module {
3
+ background-color: var(--color-5);
4
+ }
5
+ }
6
+ .carouselContainer {
7
+ .carouselTitle {
8
+ margin-bottom: 1.5rem;
9
+ }
10
+ .slide {
11
+ display: flex;
12
+ flex-direction: row;
13
+ align-items: center;
14
+ width: 100%;
15
+ }
16
+ .carouselItem {
17
+ padding: 0.5rem;
18
+ width: 50%;
19
+ @include max(tablet) {
20
+ width: 100%;
21
+ text-align: center;
22
+ }
23
+ img {
24
+ border-radius: 0.6rem;
25
+ }
26
+ }
3
27
  }
@@ -6,6 +6,7 @@ import PropTypes from 'prop-types';
6
6
  import { schemaGenerator } from '~helpers/schema';
7
7
  import { getUrl, getPageImage, imagePrettyUrl } from '~helpers/getters';
8
8
  import keygen from '~helpers/keygen';
9
+ import { getTwitterUsername } from '../../../../helpers/strings';
9
10
 
10
11
  export function getLanguage(language) {
11
12
  const name = process.env.GATSBY_SITE_NAME;
@@ -43,41 +44,55 @@ function setName(string) {
43
44
  }
44
45
  const Head = ({ page = {}, siteInfo }) => {
45
46
  const pageImage = getPageImage(page) ? getPageImage(page) : imagePrettyUrl(siteInfo?.site_logo);
46
- // When google re-indexes dev NSA and IRL, remove lines 28, 41, 42, 43 and process.env.GATSBY_ACTIVE_ENV !== 'development' from lines 24, 25, 27, 29, 43
47
+ const twitterUsername = getTwitterUsername(page.siteSchema?.twitter);
48
+
47
49
  return (
48
- <Helmet>
49
- <meta charSet="utf-8" />
50
- <title>{page.meta_title}</title>
51
- <html lang={getLanguage(page.language)} />
52
- <meta name="description" content={page.meta_description} />
53
- {page.meta_robots && process.env.GATSBY_ACTIVE_ENV !== 'development' && (
54
- <meta name="robots" content={page.meta_robots.join()} />
55
- )}
56
- {page.robot_options && !page.path.includes('/page/') && (
57
- <meta name="robots" content={getRobotOptions(page.robot_options)} />
58
- )}
59
- {page.path.includes('/page/') && <meta name="robots" content="noindex,follow" />}
60
- {process.env.GATSBY_ACTIVE_ENV === 'development' && (
61
- <meta name="googlebot" content="noindex,follow" />
62
- )}
63
- <link rel="canonical" href={getCanonicalUrl(page)} />
64
- {page.preconnect_links &&
65
- page.preconnect_links.map((link) => <link key={keygen()} rel="preconnect" href={link} />)}
66
- <meta name="og:title" content={page.meta_title} />
67
- <meta name="og:site_name" content={siteInfo?.site_name && setName(siteInfo?.site_name)} />
68
- <meta name="og:description" content={page.meta_description} />
69
- <meta name="og:type" content={page.path === '/' ? 'website' : 'article'} />
70
- <meta name="og:image" content={pageImage} />
71
- <meta name="og:url" content={getUrl(page.path)} />
72
- {schemaGenerator(page, pageImage).map(
73
- (schema) =>
74
- schema && (
75
- <script key={keygen()} type="application/ld+json">
76
- {`${schema}`}
77
- </script>
78
- )
50
+ <>
51
+ <Helmet>
52
+ <meta charSet="utf-8" />
53
+ <title>{page.meta_title}</title>
54
+ <html lang={getLanguage(page.language)} />
55
+ <meta name="description" content={page.meta_description} />
56
+ {page.meta_robots && process.env.GATSBY_ACTIVE_ENV !== 'development' && (
57
+ <meta name="robots" content={page.meta_robots.join()} />
58
+ )}
59
+ {page.robot_options && !page.path.includes('/page/') && (
60
+ <meta name="robots" content={getRobotOptions(page.robot_options)} />
61
+ )}
62
+ {page.path.includes('/page/') && <meta name="robots" content="noindex,follow" />}
63
+ {process.env.GATSBY_ACTIVE_ENV === 'development' && (
64
+ <meta name="googlebot" content="noindex,follow" />
65
+ )}
66
+ <link rel="canonical" href={getCanonicalUrl(page)} />
67
+ {page.preconnect_links &&
68
+ page.preconnect_links.map((link) => <link key={keygen()} rel="preconnect" href={link} />)}
69
+ <meta name="og:title" content={page.meta_title} />
70
+ <meta name="og:site_name" content={siteInfo?.site_name && setName(siteInfo?.site_name)} />
71
+ <meta name="og:description" content={page.meta_description} />
72
+ <meta name="og:type" content={page.path === '/' ? 'website' : 'article'} />
73
+ <meta name="og:image" content={pageImage} />
74
+ <meta name="og:url" content={getUrl(page.path)} />
75
+
76
+ {schemaGenerator(page, pageImage).map(
77
+ (schema) =>
78
+ schema && (
79
+ <script key={keygen()} type="application/ld+json">
80
+ {`${schema}`}
81
+ </script>
82
+ )
83
+ )}
84
+ </Helmet>
85
+
86
+ {twitterUsername && (
87
+ <Helmet>
88
+ <meta name="twitter:title" content={page.meta_title} />
89
+ <meta name="twitter:description" content={page.meta_description} />
90
+ <meta name="twitter:site" content={twitterUsername} />
91
+ <meta name="twitter:card" content="summary" />
92
+ <meta name="twitter:image" content={pageImage} />
93
+ </Helmet>
79
94
  )}
80
- </Helmet>
95
+ </>
81
96
  );
82
97
  };
83
98
 
@@ -12,6 +12,14 @@
12
12
  --modal-background-color: white;
13
13
 
14
14
  --star-rating-color: orange;
15
+ --full-star-fill-color: #fba62f;
16
+ --full-star-border-color: #fba62f;
17
+ --halfFull-star-fill-color: #fba62f;
18
+ --halfEmpty-star-fill-color: white;
19
+ --half-star-border-color: #fba62f;
20
+ --empty-star-fill-color: white;
21
+ --empty-star-border-color: grey;
22
+ --selling-point-icon-color: #00889e;
15
23
 
16
24
  --main-font: sans-serif;
17
25
 
@@ -64,4 +72,6 @@
64
72
  --page-number-background: #393939;
65
73
  --page-number-color: #fff;
66
74
  --sitemap-background-color: #fff;
75
+
76
+
67
77
  }
@@ -1,34 +1,45 @@
1
1
  export function capitalize(string) {
2
- return string.replace(/^\w/, (c) => c.toUpperCase());
2
+ return string.replace(/^\w/, (c) => c.toUpperCase());
3
+ }
4
+
5
+ export function anchorLink(string) {
6
+ return string.replace(/\s/g, '-').toLowerCase();
7
+ }
8
+
9
+ export function leftTrim(str) {
10
+ if (!str) return str;
11
+ // remove space from begining
12
+ const trim = str.replace(/^\s+/g, '');
13
+ // remove multiple spaces
14
+ const output = trim.replace(/ +(?= )/g, '');
15
+ return output;
16
+ }
17
+
18
+ export function truncateString(str, num, dots = '...') {
19
+ if (!str || str.length <= num) {
20
+ return str;
3
21
  }
4
-
5
- export function anchorLink(string) {
6
- return string.replace(/\s/g, '-').toLowerCase();
7
- }
8
-
9
- export function leftTrim(str) {
10
- if (!str) return str;
11
- // remove space from begining
12
- const trim = str.replace(/^\s+/g, '');
13
- // remove multiple spaces
14
- const output = trim.replace(/ +(?= )/g, '');
15
- return output;
22
+ let trimmedString = str.substr(0, num);
23
+
24
+ if (str.charAt(num) === ' ') {
25
+ return `${trimmedString}${dots}`;
16
26
  }
17
-
18
- export function truncateString(str, num, dots = '...') {
19
- if (!str || str.length <= num) {
20
- return str;
21
- }
22
- let trimmedString = str.substr(0, num);
23
-
24
- if (str.charAt(num) === ' ') {
25
- return `${trimmedString}${dots}`;
26
- }
27
- const hasSpace = trimmedString.lastIndexOf(' ') !== -1;
28
- if (!hasSpace) {
29
- return `${trimmedString}${dots}`;
30
- }
31
- trimmedString = trimmedString.substr(0, trimmedString.lastIndexOf(' '));
27
+ const hasSpace = trimmedString.lastIndexOf(' ') !== -1;
28
+ if (!hasSpace) {
32
29
  return `${trimmedString}${dots}`;
33
30
  }
34
-
31
+ trimmedString = trimmedString.substr(0, trimmedString.lastIndexOf(' '));
32
+ return `${trimmedString}${dots}`;
33
+ }
34
+
35
+ export function getTwitterUsername(url) {
36
+ // eslint-disable-next-line no-useless-escape
37
+ const regex = /https?:\/\/(www\.)?twitter\.com\/(#!\/)?@?([^\/]*)/;
38
+ const m = regex.exec(url);
39
+
40
+ if (m !== null && m.length >= 3) {
41
+ return m[3];
42
+ }
43
+
44
+ return null;
45
+ }