google / WebFundamentals

Former git repo for WebFundamentals on developers.google.com
Apache License 2.0
13.85k stars 2.57k forks source link

web share API share files (temp files) #7897

Closed anik587 closed 5 years ago

anik587 commented 5 years ago

Hello, I have been working with web share API and followed below blog for implementation, which is working but with few issues Page Affected:https://developers.google.com/web/updates/2019/05/web-share-files

Check this code please, here I am generating an image from Html my image is generating perfectly my share option is working but my files gettings corrupted. when I'm sharing in facebook messenger it can't share though its shares in skype but gets corrupted

        htmlToImage.toPng(document.getElementById('my-node'))
            .then(function (blob) {
                let img = new Image();
                img.src = blob;
                    console.log([new File([img], "filename.png", {type: "image/png", path: blob})]);
                   if (window.navigator.canShare && window.navigator.canShare( { files: [new File([img], "filename.png", {type: "image/png", path: blob})] } )) {
                        window.navigator.share({
                            files: [new File([img], "filename.png", {type: "image/png", path: blob})],
                            title: 'Vacation Pictures',
                            text: 'Barb\nHere are the pictures from our vacation.\n\nJoe',
                        })
                            .then(() => alert('Share was successful.'))
                            .catch((error) => alert(error, error));
                    } else {
                        alert('Your system doesn\'t support sharing files.');
                    }
                }
            );
    };
anik587 commented 5 years ago

solved it only accepts blob :D just use toBlob

Marcio0101 commented 5 years ago

Hello, I could append the example code with the changes.

anik587 commented 5 years ago

Hey, I am working on react so I just shared my method here. Now I am pasting my hole component code but you can ignore most of them.

import React, { useRef } from 'react';
import ReactToPrint from "react-to-print";
import Auxi from '../../../../hoc/Auxi';
import getSession from '../../../UI/Session/getSession';
import moment from 'moment';
import ReactHtmlParser from 'react-html-parser';
import * as htmlToImage from 'html-to-image';
import saveAs from 'file-saver';

export default (props)=>{

/*
    const  formatDate=(date)=> {
        let monthNames = [
            "January", "February", "March",
            "April", "May", "June", "July",
            "August", "September", "October",
            "November", "December"
        ];
        let monthIndex = date.getMonth();
        let year = date.getFullYear();

        return monthNames[monthIndex] + ', ' + year;
    };*/

    const share = ()=>{

        htmlToImage.toBlob(document.getElementById('my-node'))
            .then(function (blob) {

                    if (window.navigator.canShare && window.navigator.canShare( { files: [new File([blob], "invoice.png", {type: "image/png", mimeType: 'image/png'})] } )) {
                        window.navigator.share({
                            files: [new File([blob], "invoice.png", {type: "image/png"})],
                        }).then(() => console.log('Share was successful.'))
                            .catch((error) => console.log(error, error));
                    } else {
                        saveAs(blob, 'invoice.png');
                    }

            }
            );
    };

    const toggleShare = ()=>{
        if(!window.$('#mediaShare').hasClass('show')){
            window.$('#mediaShare').addClass('show');
            window.$('#mask').addClass('show');
        }else{
            document.body.className= "left-sidebar-fixed left-sidebar-light header-fixed";
            window.$('#mediaShare').removeClass('show');
            window.$('#mask').removeClass('show');

        }
    };

    let sessionData = getSession('sessionData');
    const componentRef = useRef();

        return(
            <Auxi>

                {props.allowSales ?
                    <div className="card text-center mb-4">
                        <div className="card-body py-lg-4">
                            <h4 className="weight600 mb-4">Save as a Sales?</h4>
                            <button type="button" onClick={(e)=>{ props.saveSales();}} className="btn btn-sm btn-primary mx-1">Yes</button>
                            <button type="button" onClick={(e)=>{ props.cancelSales();}} className="btn btn-sm btn-outline-primary mx-1">No</button>
                        </div>
                    </div> : ''}

                <div className="card" ref={componentRef} id="my-node">

                    <div className="done-msg text-center border-bottom pb-3">
                            <span className="done-icon">
                                <i className="si-tick"/>
                            </span>
                        <h4>{props.title}</h4>
                        <p className="tran-id">Transaction ID <span>{props.invoice.TransactionId}</span></p>
                        <p className="text-muted">{moment().format('MMMM Do YYYY, h:mm a')}</p>
                    </div>
                    <div className="done-msg text-center border-bottom pb-3">
                        <h4 className="mb-0">{sessionData.fullName}</h4>
                        <p className="text-muted mb-0">{sessionData.mobileNo}</p>
                        <p className="text-muted">{sessionData.email}</p>
                    </div>

                    <div className="card-body">
                        <form className="p-lg-3">
                            {Object.keys(props.invoice).map((d,i)=>{
                                if(d !== 'TransactionId'){
                                    return <div className="row border-bottom pb-3 mb-3" key={i}>
                                        <div className="col-5">{d.replace('_', ' ')}</div>
                                        <div className="col-7 text-right weight600">{ReactHtmlParser(props.invoice[d])}</div>
                                    </div>
                                }else{
                                    return '';
                                }
                            })}
                        </form>
                    </div>

                </div>
                <div className="share-media-option">
                    <div id="mediaShare" className="share-media">

                        <ReactToPrint
                            trigger={() => <a href="javascript:void(0)" className="print"><i className="si-print"/> <span>Print</span></a>}
                            content={() => componentRef.current}
                        />

                    </div>
                    <a href="javascript:;" onClick={(e)=>toggleShare()}  className="media-btn">
                        <i className="si-more-menu"/></a>
                    <div id="mask" className="mask"/>
                </div>

                <div className="text-center">
                    <button onClick={(e)=>{share()}} type="button" className="btn btn-primary btn-block">
                        Share
                    </button>
                    <button onClick={(e)=>{props.restartProcess()}} type="button" className="btn btn-outline-primary btn-block mt-3">Add Another {props.name}</button>
                </div>
            </Auxi>
        )
}

Just look into share method eventually the following code you only need if you want to share a file using web.share. If you are using pure JS ignore all window

 if (window.navigator.canShare && window.navigator.canShare( { files: [new File([blob], "invoice.png", {type: "image/png", mimeType: 'image/png'})] } )) {
                        window.navigator.share({
                            files: [new File([blob], "invoice.png", {type: "image/png"})],
                        }).then(() => console.log('Share was successful.'))
                            .catch((error) => console.log(error, error));
                    } else {
                        saveAs(blob, 'invoice.png');
                    }
Marcio0101 commented 5 years ago

Thank you very much

Marcio0101 commented 5 years ago

It worked perfectly, Very warm, it helped me a lot.

Marcio0101 commented 5 years ago

in IOS Change something or the code is the same?

anik587 commented 5 years ago

Tested on safari worked so hope for the best