UNPKG

react-crop-upload-pictures

Version:
214 lines 10.9 kB
import React, { useCallback, useState, forwardRef, useImperativeHandle, useEffect } from "react"; import { Button } from 'react-bootstrap'; import ApiCall from './Helper/ApiCall.js'; import FacebookLogin from 'react-facebook-login/dist/facebook-login-render-props'; import { LazyLoadImage } from "react-lazy-load-image-component"; import "../assets/style/index.scss"; const ERROR = { NOT_SUPPORTED_EXTENSION: 'NOT_SUPPORTED_EXTENSION', FILE_SIZE_TOO_LARGE: 'FILE_SIZE_TOO_LARGE', DIMENSION_IMAGE: "DIMENSION_IMAGE" }; const LoadingIndicator = () => (React.createElement("div", { className: "d-flex justify-content-center mt-3" }, React.createElement("div", { className: "spinner-border", role: "status" }, React.createElement("span", { className: "sr-only" }, "Loading...")))); const SocialMediaImportPopup = forwardRef(({ title = null, modalSource = null, height = "200px", width = "200px", classStyle = "", iconSize = "lg", handleClose = () => { }, setPhotosCallback = () => { }, token = '', multiple = false, }, ref) => { useImperativeHandle(ref, () => ({ getErrors() { return []; }, getPictures() { return pictures; }, })); const [instagramUserId, setInstagramUserId] = useState(null); const [pictures, setPictures] = useState([]); const [selected, setSelected] = useState([]); const [currentToken, setCurrentToken] = useState(token); const [isPulled, setIsPulled] = useState(false); const [loading, setLoading] = useState(false); const readTokenAndTimestamp = useCallback(() => { const rawData = localStorage.getItem(`${modalSource}Token`); if (!rawData) { return [null, null]; } const pieces = rawData.split('~~'); const accessToken = pieces?.[0]; const timestamp = parseInt(pieces?.[1]); if (Date.now() - timestamp > 3598 * 1000) { localStorage.removeItem(`${modalSource}Token`); return [null, null]; } return [accessToken, timestamp]; }, [modalSource]); const setTokenAndTimestamp = useCallback((accessToken) => { localStorage.setItem(`${modalSource}Token`, `${accessToken}~~${Date.now()}`); setCurrentToken(accessToken); }, [modalSource]); const getInstagramAccessCode = () => { const params = new URL(document.location.toString()).searchParams; return params.get("code"); }; useEffect(() => { setPhotosCallback([], []); const pieces = readTokenAndTimestamp(); const accessToken = pieces?.[0]; const instagramAccessCode = getInstagramAccessCode(); if (accessToken && !currentToken) { setCurrentToken(accessToken); } else if (!accessToken && !instagramAccessCode && modalSource === 'instagram') { window.location.href = "https://api.instagram.com/oauth/authorize?client_id=" + process.env.REACT_APP_INSTAGRAM_APP_ID + "&redirect_uri=" + window.location.origin + "/callback/instagram" + "&scope=user_profile,user_media&response_type=code"; } else if (!accessToken && instagramAccessCode && modalSource === 'instagram') { const getAndSetInstagramAccessToken = async (accessCode) => { try { const result = await ApiCall.post('account/social/exchange/instagram', { accessCode, redirectUri: window.location.origin + "/callback/instagram" }); if (result?.data && result?.data?.access_token) { setTokenAndTimestamp(result?.data?.access_token); } else { handleClose(); } } catch { handleClose(); } }; getAndSetInstagramAccessToken(instagramAccessCode); } if (!isPulled) { switch (modalSource) { case "facebook": FBGetPhotos(); break; case "instagram": InstagramGetPhotos(); break; } } }, [modalSource, currentToken, isPulled]); async function fetchFBPic(path, accessToken) { const response = await fetch(`https://graph.facebook.com/${path}&access_token=${accessToken}`); return await response.json(); } async function fetchInstagramPic(accessToken, userId) { const response = await fetch(`https://graph.instagram.com/${userId?.id}/media?access_token=${accessToken}`); return await response.json(); } const getAlbums = useCallback(async (takeFromFB = true) => { const userId = await (await fetch(`https://graph.instagram.com/me?fields=id,username&access_token=${currentToken}`))?.json(); setInstagramUserId(userId?.username); const response = takeFromFB ? await fetchFBPic('me/albums?fields=id,name', currentToken) : await fetchInstagramPic(currentToken, userId); if (response.data && response.data.length > 0) { if (takeFromFB) { await response.data.forEach(async (album) => { if (album.name === "Profile pictures") { let data = await getPhotosForAlbumId(album.id, currentToken); let results = []; results = data.map((item, index) => ({ src: item.source })); if (results) { setPictures([...pictures, ...results]); } } }); } else { const results = await Promise.all(response.data.map(async (item, index) => { const data = await getPhotoForInstaPhotoId(item?.id, currentToken); return { src: data?.media_url }; })); if (results) { setPictures([...pictures, ...results]); } } } setLoading(false); setIsPulled(true); }, [[...pictures], currentToken]); async function getPhotosForAlbumId(albumId, accessToken) { const response = await fetchFBPic(`${albumId}/photos?fields=source`, accessToken); return await response.data && response.data.length > 0 ? response.data : []; } async function getPhotoForInstaPhotoId(photoId, accessToken) { const response = await fetch(`https://graph.instagram.com/${photoId}?access_token=${accessToken}&fields=media_url,permalink`); return await response.json(); } async function FBGetPhotos() { setLoading(true); if (currentToken) { await getAlbums(); } else { setLoading(false); } } async function InstagramGetPhotos() { setLoading(true); if (currentToken) { await getAlbums(false); } else { setLoading(false); } } const toggleMarkSelected = useCallback((pos) => { let result; if (!multiple) { if (selected.includes(pos)) { setSelected([]); setPhotosCallback(pictures, []); } else { result = [pos]; setSelected(result); setPhotosCallback(pictures, result); } } else { if (selected.includes(pos)) { result = selected.filter(el => el !== pos); setSelected(result); setPhotosCallback(pictures, result); } else { result = [...selected, pos]; setSelected(result); setPhotosCallback(pictures, result); } } }, [pictures, selected, multiple]); const responseFacebook = (response) => { if (response && response?.accessToken) { setTokenAndTimestamp(response.accessToken); } else { handleClose(); } }; return (React.createElement(React.Fragment, null, React.createElement("div", { ref: ref, style: { minHeight: 480, maxHeight: 800, overflowY: "auto", overflowX: "hidden" } }, React.createElement("div", { className: classStyle }, React.createElement("div", { className: "upload-content" }, title !== null ? React.createElement("div", { className: "upload-header" }, React.createElement("h1", { className: "upload-title fs-5" }, title)) : "", React.createElement("div", { className: "mb-2" }, React.createElement("div", { className: "alert alert-info", role: "alert" }, instagramUserId !== null ? `Photos of ${instagramUserId}. (${selected?.length}) pictures selected` : `Loading...`)), React.createElement("div", { className: "mb-5 upload-body" }, React.createElement("div", { className: "row justify-content-center mb-5" }, React.createElement("div", { className: "col", style: { width: "auto" } })), loading && React.createElement(LoadingIndicator, null), !currentToken && modalSource === 'facebook' && (React.createElement("div", { className: "d-flex justify-content-center", style: { marginTop: 104 } }, React.createElement(FacebookLogin, { appId: process.env.REACT_APP_FACEBOOK_APP_ID, autoLoad: true, fields: "name,email,picture", scope: "public_profile,user_friends,user_photos", render: renderProps => (React.createElement(Button, { variant: "primary", className: "text-white", onClick: renderProps.onClick }, "Please click here to authorize your Facebook profile")), callback: responseFacebook }))), React.createElement("div", { className: "row d-flex justify-content-center space-photos" }, pictures.length > 0 && (React.createElement("div", { className: "row d-flex justify-content-center" }, pictures.map((picture, index) => (React.createElement("div", { className: `position-relative p-0 mx-2 mb-4 social-media ${selected.includes(index) ? 'selected' : ''}`, key: index, style: { width: width, height: height }, onClick: () => toggleMarkSelected(index) }, React.createElement(ImageDisplay, { picture: picture, height: height, width: width, className: "mb-4" }))))))))))))); }); function ImageDisplay({ picture, width, height }) { return React.createElement(LazyLoadImage, { src: picture?.src, style: { height: height, width: width, }, alt: "Social media picture", effect: "opacity", width: width, height: height, placeholder: React.createElement(LoadingIndicator, null) }); } export default SocialMediaImportPopup; //# sourceMappingURL=socialMediaImportPopup.js.map