Procházet zdrojové kódy

add share button with alternative if API not supported

Ramona Plogmann před 4 roky
rodič
revize
48dfd26f12

+ 3 - 24
client/src/components/Meals/MealDetailView.jsx

@@ -1,6 +1,5 @@
 import React, { useEffect, useState } from 'react';
-import { Box, Grid, IconButton, Link, Typography } from '@material-ui/core';
-import { Share } from '@material-ui/icons';
+import { Box, Grid, Link, Typography } from '@material-ui/core';
 import { makeStyles } from '@material-ui/styles';
 import { arrayOf, bool, func, shape, string } from "prop-types";
 import EditMeal from "./EditMeal";
@@ -11,7 +10,7 @@ import { useTranslation } from "react-i18next";
 import EditButton from "../Buttons/EditButton";
 import FullScreenDialog from "../util/FullScreenDialog";
 import { fetchAndUpdateMeal } from "./meals.util";
-import { useAuth0 } from "@auth0/auth0-react";
+import ShareButton from "../util/ShareButton";
 
 const useStyles = makeStyles((theme) => ({
   content: {
@@ -32,7 +31,6 @@ const useStyles = makeStyles((theme) => ({
 const MealDetailView = (props) => {
   const classes = useStyles();
   const { t } = useTranslation();
-  const { user } = useAuth0();
 
   const { meal: initialMeal, open, closeDialog, onDoneEditing, allowEditing, extern } = props;
 
@@ -61,22 +59,6 @@ const MealDetailView = (props) => {
     fetchMeal();
   }
 
-  const shareMeal = () => {
-    const linkToMeal = window.location.origin + '/meals/view/' + meal._id;
-    console.log('share meal', linkToMeal);
-    if (navigator.share) {
-      navigator.share({
-        title: meal.title + ' von ' + user.name,
-        url: linkToMeal,
-      }).then(() => {
-        alert('Web Share API vorhanden!!! Danke, dass Sie uns heute besucht haben ;)');
-        console.log('Thanks for sharing!');
-      }).catch(console.error);
-    } else {
-      alert('Web Share API nicht vorhanden.');
-    }
-  }
-
   const rightSideComponent = <>
     {allowEditing && <EditButton onClick={() => {openEditItemDialog(meal)}} />}
   </>;
@@ -92,10 +74,7 @@ const MealDetailView = (props) => {
                 <Typography variant="h4">{meal.title}</Typography>
               </Grid>
               <Grid item xs className={classes.shareButton}>
-                <IconButton variant="outlined" onClick={shareMeal}>
-                  <Share />
-                  {/*<FontAwesomeIcon icon={faShareSquare} />*/}
-                </IconButton>
+                <ShareButton link={window.location.origin + '/meals/view/' + meal._id} title={meal.title} />
               </Grid>
             </Grid>
             {meal.recipeLink ? <Typography><Link href={meal.recipeLink} target="_blank">{meal.recipeLink}</Link></Typography> : ''}

+ 75 - 0
client/src/components/util/ShareButton.jsx

@@ -0,0 +1,75 @@
+import React, { useState } from 'react';
+import { IconButton, Button, DialogTitle, Dialog, TextField, InputAdornment, Grid } from '@material-ui/core';
+import { Share, Link, FileCopy, AssignmentTurnedInRounded } from '@material-ui/icons';
+import { string } from "prop-types";
+
+/** Button that opens native share API on the devices or provides the link if API is not supported */
+const ShareButton = (props) => {
+  const { title, link } = props;
+  const [isCopyLinkOpen, setIsCopyLinkOpen] = useState(false);
+  const [isCopied, setIsCopied] = useState(false);
+
+  const share = () => {
+    console.log('share ', link);
+    if (navigator.share) {
+      navigator.share({
+        title,
+        url: link,
+      }).then(() => {
+        console.log('Thanks for sharing!');
+      }).catch(console.error);
+    } else {
+      setIsCopyLinkOpen(true);
+    }
+  }
+
+  const copyToClipboard = () => {
+    // logic from https://www.w3schools.com/howto/howto_js_copy_clipboard.asp
+    /* Get the text field */
+    const copyText = document.getElementById("link-input");
+
+    /* Select the text field */
+    copyText.select();
+    copyText.setSelectionRange(0, 99999); /* For mobile devices */
+
+    /* Copy the text inside the text field */
+    document.execCommand("copy");
+
+    setIsCopied(true);
+  }
+
+  return (
+    <>
+      <IconButton variant="outlined" onClick={share}>
+        <Share />
+        {/*<FontAwesomeIcon icon={faShareSquare} />*/}
+      </IconButton>
+      <Dialog open={isCopyLinkOpen} onClose={() => {setIsCopyLinkOpen(false)}} PaperProps={{style: {padding: '2em'}}}>
+        <DialogTitle style={{padding: '0 0 0.5em'}}>{title}</DialogTitle>
+        <Grid container spacing={2} justify="space-between" alignItems="center" wrap="wrap">
+          <Grid item xs style={{flexGrow: 5}}>
+          <TextField id="link-input" variant="standard" value={link} color="secondary" InputProps={{
+            startAdornment: (
+              <InputAdornment position="start">
+                <Link />
+              </InputAdornment>
+            ),
+          }} />
+          </Grid>
+          <Grid item xs>
+          <Button startIcon={isCopied ? <AssignmentTurnedInRounded /> : <FileCopy />} variant="contained" color={"secondary"} onClick={copyToClipboard}>
+            {isCopied ? 'Copied' : 'Copy'}
+          </Button>
+        </Grid>
+        </Grid>
+      </Dialog>
+    </>
+  );
+}
+
+ShareButton.propTypes = {
+  link: string.isRequired,
+  title: string.isRequired,
+}
+
+export default ShareButton;