Skip to content

Commit

Permalink
Add possibility to create shortened share links (#8)
Browse files Browse the repository at this point in the history
* Add possibility to create shortened share links

#3

* Update package-lock.json

* Apply minor code tweaks

* Make QR code dependent on short link switch

* Use short links by default

Co-authored-by: Nees Jan van Eck <ecknjpvan@cwts.leidenuniv.nl>
  • Loading branch information
Stukova and neesjanvaneck authored Dec 24, 2021
1 parent afd71b3 commit bbfbdc0
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 20 deletions.
11 changes: 11 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"react-helmet": "^6.1.0",
"react-html-parser": "^2.0.2",
"react-router-dom": "^5.0.1",
"tinyurl": "^1.1.7",
"use-debounce": "0.0.7"
},
"devDependencies": {
Expand Down
52 changes: 37 additions & 15 deletions src/components/ui/Share/index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
/* eslint-disable no-undef */
/* eslint-disable jsx-a11y/anchor-is-valid */
/* eslint-disable jsx-a11y/anchor-has-content */
import React, { useContext, useRef, useState } from 'react';
import React, { useContext, useEffect, useRef, useState } from 'react';
import { observer } from 'mobx-react-lite';
import {
Button, Dialog, DialogActions, DialogContent, DialogTitle, IconButton, TextField, Tooltip, Typography
Button, Dialog, DialogActions, DialogContent, DialogTitle, FormControlLabel, IconButton, Switch, TextField, Tooltip, Typography
} from '@material-ui/core';
import CloseIcon from '@material-ui/icons/Close';
import ShareIcon from '@material-ui/icons/Share';
import TinyURL from 'tinyurl';
import QRCode from 'qrcode.react';
import _cloneDeep from 'lodash/cloneDeep';

Expand All @@ -21,8 +22,16 @@ const Share = observer(() => {
const queryStringStore = useContext(QueryStringStoreContext);
const uiStore = useContext(UiStoreContext);
const [isOpen, setIsOpen] = useState(false);
const [useShortLink, setUseShortLink] = useState(true);
const [link, setLink] = useState('');
const [embedCode, setEmbedCode] = useState('');
const qrImageEl = useRef(null);

useEffect(async () => {
setLink(useShortLink ? await getShortenedLink() : getLink());
setEmbedCode(getEmbedCode(useShortLink ? await getShortenedLink(true) : getLink(true)));
});

const showShareDialog = () => {
setIsOpen(!isOpen);
};
Expand All @@ -38,7 +47,7 @@ const Share = observer(() => {
qrImageEl.current.click();
};

const copyImageToClipboard = (id) => {
const copyQRImageToClipboard = (id) => {
const canvas = document.getElementById(id);
canvas.toBlob(blob => navigator.clipboard.write([new ClipboardItem({ 'image/png': blob })]));
};
Expand All @@ -53,22 +62,21 @@ const Share = observer(() => {
}
};

const getShareURL = () => {
const getLink = (isEmbedded = false) => {
const { origin, pathname } = window.location;
const queryObject = getQueryObject();
if (isEmbedded) queryObject[parameterKeys.SIMPLE_UI] = true;
const queryString = Object.keys(queryObject).reduce((acc, key, idx) => `${acc}${idx === 0 ? '?' : '&'}${key}=${queryObject[key]}`, '');
return `${origin}${pathname}${queryString}`;
};

const getEmbedCode = () => {
const { origin, pathname } = window.location;
const queryObject = getQueryObject();
queryObject[parameterKeys.SIMPLE_UI] = true;
const queryString = Object.keys(queryObject).reduce((acc, key, idx) => `${acc}${idx === 0 ? '?' : '&'}${key}=${queryObject[key]}`, '');
const embedUrl = `${origin}${pathname}${queryString}`;
return `<iframe allowfullscreen="true" src="${embedUrl}" width="100%" height="75%" style="border: 1px solid #ddd; max-width: 1000px; min-height: 500px"></iframe>`;
const getShortenedLink = async (isEmbedded = false) => {
const url = await TinyURL.shorten(getLink(isEmbedded));
return url;
};

const getEmbedCode = (url) => `<iframe allowfullscreen="true" src="${url}" width="100%" height="75%" style="border: 1px solid #ddd; max-width: 1000px; min-height: 500px"></iframe>`;

const getQueryObject = () => {
const result = _cloneDeep(queryStringStore.parameters);
if (result[parameterKeys.JSON]) {
Expand Down Expand Up @@ -113,7 +121,7 @@ const Share = observer(() => {
<a ref={qrImageEl} style={{ display: 'none' }} />
<QRCode
id="qr-code-image"
value={getShareURL()}
value={link}
size={90}
level="L"
renderAs="canvas"
Expand All @@ -129,7 +137,7 @@ const Share = observer(() => {
<Button
className={s.copyButton}
variant="outlined"
onClick={() => copyImageToClipboard('qr-code-image')}
onClick={() => copyQRImageToClipboard('qr-code-image')}
>
Copy
</Button>
Expand All @@ -141,14 +149,28 @@ const Share = observer(() => {
Download
</Button>
</div>
<div className={s.switchBox}>
<FormControlLabel
classes={{ label: s.switchLabel }}
control={(
<Switch
checked={useShortLink}
onChange={event => setUseShortLink(event.target.checked)}
color="primary"
/>
)}
label="Short link"
labelPlacement="start"
/>
</div>
<div className={s.inputBox}>
<TextField
id="share-link-input"
className={s.input}
label="Link"
multiline
maxRows={3}
defaultValue={getShareURL()}
value={link}
InputProps={{ readOnly: true }}
/>
<Button
Expand All @@ -166,7 +188,7 @@ const Share = observer(() => {
label="Embed code"
multiline
maxRows={3}
defaultValue={getEmbedCode()}
value={embedCode}
InputProps={{ readOnly: true }}
/>
<Button
Expand Down
24 changes: 19 additions & 5 deletions src/components/ui/Share/styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ export const dialogContent = css`
`;

export const qrCodeLabel = css`
label: qr-label;
transform: scale(0.75);
transform-origin: top left;
opacity: 0.65;
font-size: 1rem;
label: qr-label;
transform: scale(0.75);
transform-origin: top left;
opacity: 0.65;
font-size: 1rem;
`;

export const qrCodeBox = css`
Expand Down Expand Up @@ -61,3 +61,17 @@ export const downloadButton = css`
margin-bottom: 20px !important;
margin-left: 20px !important;
`;

export const switchBox = css`
label: switch-box;
margin-top: 16px;
`;

export const switchLabel = css`
label: switch-label;
margin-left: -16px !important;
transform: scale(0.75);
transform-origin: left;
opacity: 0.65;
font-size: 1rem !important;
`;

0 comments on commit bbfbdc0

Please sign in to comment.