diff --git a/src/main/resources/static/css/fileSelect.css b/src/main/resources/static/css/fileSelect.css index 579135c3d..61dc9963f 100644 --- a/src/main/resources/static/css/fileSelect.css +++ b/src/main/resources/static/css/fileSelect.css @@ -273,10 +273,10 @@ } -.googleDriveButton { +.google-drive-button { width: 2.5rem; pointer-events: auto; } -.googleDriveButton img { +.google-drive-button img { width:100% } \ No newline at end of file diff --git a/src/main/resources/static/js/fileInput.js b/src/main/resources/static/js/fileInput.js index 8079cdb3e..2d15751b6 100644 --- a/src/main/resources/static/js/fileInput.js +++ b/src/main/resources/static/js/fileInput.js @@ -35,6 +35,7 @@ function setupFileInput(chooser) { const pdfPrompt = chooser.getAttribute('data-bs-pdf-prompt'); const inputContainerId = chooser.getAttribute('data-bs-element-container-id'); const showUploads = chooser.getAttribute('data-bs-show-uploads') === "true"; + const name = chooser.getAttribute('data-bs-unique-id') let inputContainer = document.getElementById(inputContainerId); const input = document.getElementById(elementId); @@ -145,7 +146,7 @@ function setupFileInput(chooser) { document.body.addEventListener('dragenter', dragenterListener); document.body.addEventListener('dragleave', dragleaveListener); document.body.addEventListener('drop', dropListener); - document.body.addEventListener('googleDriveFilePicked', googleDriveFileListener); + document.body.addEventListener(name + 'GoogleDriveDrivePicked', googleDriveFileListener); $('#' + elementId).on('change', async function (e) { let element = e.target; diff --git a/src/main/resources/static/js/googleFilePicker.js b/src/main/resources/static/js/googleFilePicker.js index 1ac3d4975..205167885 100644 --- a/src/main/resources/static/js/googleFilePicker.js +++ b/src/main/resources/static/js/googleFilePicker.js @@ -1,54 +1,94 @@ - const SCOPES = 'https://www.googleapis.com/auth/drive.readonly'; - const SESSION_STORAGE_ID = "googleDrivePickerAccessToken" +const SCOPES = "https://www.googleapis.com/auth/drive.readonly"; +const SESSION_STORAGE_ID = "googleDrivePickerAccessToken"; - let tokenClient; - let accessToken = sessionStorage.getItem(SESSION_STORAGE_ID); +let tokenClient; +let accessToken = sessionStorage.getItem(SESSION_STORAGE_ID); - document.getElementById("google-drive-button").addEventListener('click', onGoogleDriveButtonClick); +let isScriptExecuted = false; +if (!isScriptExecuted) { + isScriptExecuted = true; + document.addEventListener("DOMContentLoaded", function () { + document.querySelectorAll(".google-drive-button").forEach(setupGoogleDrivePicker); + }); +} - /** - * Callback after api.js is loaded. - */ - function gapiLoaded() { - gapi.load('client:picker', initializePicker); +function gisLoaded() { + tokenClient = google.accounts.oauth2.initTokenClient({ + client_id: window.stirlingPDF.GoogleDriveClientId, + scope: SCOPES, + callback: "", // defined later + }); +} + +// add more as needed. +// Google picker is limited on what mimeTypes are supported +// Wild card are not supported +const expandableMimeTypes = { + "image/*" : ["image/jpeg", "image/png","image/svg+xml" ] +} + +function fileInputToGooglePickerMimeTypes(accept) { + + if(accept == null || accept == "" || accept.includes("*/*")){ + + // Setting null will accept all supported mimetypes + return null; } - /** - * Callback after the API client is loaded. Loads the - * discovery doc to initialize the API. - */ - async function initializePicker() { - await gapi.client.load('https://www.googleapis.com/discovery/v1/apis/drive/v3/rest'); - } + let mimeTypes = []; + accept.split(',').forEach(part => { + if(!(part in expandableMimeTypes)){ + mimeTypes.push(part); + return; + } - /** - * Callback after Google Identity Services are loaded. - */ - function gisLoaded() { - tokenClient = google.accounts.oauth2.initTokenClient({ - client_id: CLIENT_ID, - scope: SCOPES, - callback: '', // defined later + expandableMimeTypes[part].forEach(mimeType => { + mimeTypes.push(mimeType); }); - } + }); + + const mimeString = mimeTypes.join(",").replace(/\s+/g, ''); + console.log([accept, "became", mimeString]); + return mimeString; +} + +/** + * Callback after api.js is loaded. + */ +function gapiLoaded() { + gapi.load("client:picker", initializePicker); +} + +/** + * Callback after the API client is loaded. Loads the + * discovery doc to initialize the API. + */ +async function initializePicker() { + await gapi.client.load("https://www.googleapis.com/discovery/v1/apis/drive/v3/rest"); +} + +function setupGoogleDrivePicker(picker) { + + const name = picker.getAttribute('data-name'); + const accept = picker.getAttribute('data-accept'); + const multiple = picker.getAttribute('data-multiple') === "true"; + const mimeTypes = fileInputToGooglePickerMimeTypes(accept); + + picker.addEventListener("click", onGoogleDriveButtonClick); - /** - * Sign in the user upon button click. - */ function onGoogleDriveButtonClick(e) { - e.stopPropagation(); tokenClient.callback = (response) => { if (response.error !== undefined) { - throw (response); + throw response; } accessToken = response.access_token; sessionStorage.setItem(SESSION_STORAGE_ID, accessToken); - createPicker(); + createGooglePicker(); }; - tokenClient.requestAccessToken({prompt: accessToken === null? 'consent' : ''}); + tokenClient.requestAccessToken({ prompt: accessToken === null ? "consent" : "" }); } /** @@ -56,36 +96,35 @@ */ function signOut() { if (accessToken) { - sessionStorage.removeItem(SESSION_STORAGE_ID); google.accounts.oauth2.revoke(accessToken); accessToken = null; } } - /** - * Create and render a Picker object for searching images. - */ - function createPicker() { - const picker = new google.picker.PickerBuilder() - .enableFeature(google.picker.Feature.MULTISELECT_ENABLED) - .setDeveloperKey(API_KEY) - .setAppId(APP_ID) - .setOAuthToken(accessToken) - .addView( - new google.picker.DocsView() - .setIncludeFolders(true) - .setMimeTypes('application/pdf,image/png,image/jpg,image/jpeg,image/svg') - ) - .addView( - new google.picker.DocsView() - .setIncludeFolders(true) - .setMimeTypes('application/pdf,image/*') - .setEnableDrives(true) - ) - .setCallback(pickerCallback) - .setTitle('Stirling PDF - Google Drive') - .build(); + function createGooglePicker() { + let builder = new google.picker.PickerBuilder() + .setDeveloperKey(window.stirlingPDF.GoogleDriveApiKey) + .setAppId(window.stirlingPDF.GoogleDriveAppId) + .setOAuthToken(accessToken) + .addView( + new google.picker.DocsView() + .setIncludeFolders(true) + .setMimeTypes(mimeTypes) + ) + .addView( + new google.picker.DocsView() + .setIncludeFolders(true) + .setEnableDrives(true) + .setMimeTypes(mimeTypes) + ) + .setCallback(pickerCallback); + + if(multiple) { + builder.enableFeature(google.picker.Feature.MULTISELECT_ENABLED); + } + const picker = builder.build(); + picker.setVisible(true); } @@ -95,23 +134,25 @@ */ async function pickerCallback(data) { if (data.action === google.picker.Action.PICKED) { - const files = await Promise.all(data[google.picker.Response.DOCUMENTS].map(async pickedFile => { - const fileId = pickedFile[google.picker.Document.ID]; - console.log(fileId); - const res = await gapi.client.drive.files.get({ - 'fileId': fileId, - 'alt': 'media', - }); - - var file = new File([new Uint8Array(res.body.length).map((_, i) => res.body.charCodeAt(i))], - pickedFile.name, { - type: pickedFile.mimeType, - lastModified: pickedFile.lastModified, - endings: pickedFile.endings - } ); - return file; - })); + const files = await Promise.all( + data[google.picker.Response.DOCUMENTS].map(async (pickedFile) => { + const fileId = pickedFile[google.picker.Document.ID]; + console.log(fileId); + const res = await gapi.client.drive.files.get({ + fileId: fileId, + alt: "media", + }); - document.body.dispatchEvent(new CustomEvent("googleDriveFilePicked", {detail: files})); + let file = new File([new Uint8Array(res.body.length).map((_, i) => res.body.charCodeAt(i))], pickedFile.name, { + type: pickedFile.mimeType, + lastModified: pickedFile.lastModified, + endings: pickedFile.endings, + }); + return file; + }) + ); + + document.body.dispatchEvent(new CustomEvent(name+"GoogleDriveDrivePicked", { detail: files })); } - } \ No newline at end of file + } +} diff --git a/src/main/resources/templates/fragments/common.html b/src/main/resources/templates/fragments/common.html index f39c5d704..b71222d63 100644 --- a/src/main/resources/templates/fragments/common.html +++ b/src/main/resources/templates/fragments/common.html @@ -245,7 +245,7 @@
-
+
google drive
@@ -268,10 +268,9 @@ \ No newline at end of file