feat(media): Embed Google Photo Picker via Popup Flow
- Revert 'Unified Embedded Picker' which caused 403 errors due to iframe restrictions on the Google Photos Picker. - Implement a 'Popup Window' flow for Google Photos selections, keeping the Media Manager active. - Restore 'Classic' Embedded Picker for Google Drive (DocsView) as it is compatible with iframes. - Update ppsscript.json with drive.photos.readonly scope for correct permissions. - Update Media Manager UI to separate Drive and Photos buttons.
This commit is contained in:
@ -404,6 +404,8 @@
|
|||||||
<div id="photos-session-status" style="font-size:11px; color:#64748b; text-align:center;">Initializing...</div>
|
<div id="photos-session-status" style="font-size:11px; color:#64748b; text-align:center;">Initializing...</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="card" style="padding-bottom: 0;">
|
<div class="card" style="padding-bottom: 0;">
|
||||||
<div class="header" style="margin-bottom:8px; display:flex; justify-content:space-between; align-items:center;">
|
<div class="header" style="margin-bottom:8px; display:flex; justify-content:space-between; align-items:center;">
|
||||||
<div style="display:flex; align-items:baseline; gap:12px;">
|
<div style="display:flex; align-items:baseline; gap:12px;">
|
||||||
@ -698,6 +700,44 @@
|
|||||||
this.saveBtn.innerText = enable ? "Save Changes" : "No Changes";
|
this.saveBtn.innerText = enable ? "Save Changes" : "No Changes";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
UI.prototype.showPhotoSession = function (url) {
|
||||||
|
var uiEl = document.getElementById('photos-session-ui');
|
||||||
|
var link = document.getElementById('photos-session-link');
|
||||||
|
var status = document.getElementById('photos-session-status');
|
||||||
|
|
||||||
|
uiEl.style.display = 'block';
|
||||||
|
link.href = url;
|
||||||
|
// We also open it automatically in a popup
|
||||||
|
const width = 1200;
|
||||||
|
const height = 800;
|
||||||
|
const left = (screen.width - width) / 2;
|
||||||
|
const top = (screen.height - height) / 2;
|
||||||
|
|
||||||
|
// Attempt popup
|
||||||
|
const popup = window.open(url, 'googlePhotos', `width=${width},height=${height},top=${top},left=${left}`);
|
||||||
|
|
||||||
|
if (popup) {
|
||||||
|
link.innerText = "Re-open Popup ↗";
|
||||||
|
link.onclick = function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
window.open(url, 'googlePhotos', `width=${width},height=${height},top=${top},left=${left}`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
link.innerText = "Open Google Photos ↗";
|
||||||
|
link.onclick = null; // Default href behavior
|
||||||
|
}
|
||||||
|
|
||||||
|
status.innerText = "Waiting for selection in popup...";
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.prototype.closePhotoSession = function () {
|
||||||
|
document.getElementById('photos-session-ui').style.display = 'none';
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.prototype.updatePhotoStatus = function (msg) {
|
||||||
|
document.getElementById('photos-session-status').innerText = msg;
|
||||||
|
};
|
||||||
|
|
||||||
UI.prototype.render = function (items) {
|
UI.prototype.render = function (items) {
|
||||||
this.grid.innerHTML = '';
|
this.grid.innerHTML = '';
|
||||||
var _this = this; // Capture 'this' for callbacks
|
var _this = this; // Capture 'this' for callbacks
|
||||||
@ -900,25 +940,6 @@
|
|||||||
document.getElementById('details-modal').style.display = 'none';
|
document.getElementById('details-modal').style.display = 'none';
|
||||||
};
|
};
|
||||||
|
|
||||||
UI.prototype.showPhotoSession = function (url) {
|
|
||||||
var uiEl = document.getElementById('photos-session-ui');
|
|
||||||
var link = document.getElementById('photos-session-link');
|
|
||||||
var status = document.getElementById('photos-session-status');
|
|
||||||
|
|
||||||
uiEl.style.display = 'block';
|
|
||||||
link.href = url;
|
|
||||||
link.style.display = 'block';
|
|
||||||
status.innerText = "Waiting for selection...";
|
|
||||||
};
|
|
||||||
|
|
||||||
UI.prototype.closePhotoSession = function () {
|
|
||||||
document.getElementById('photos-session-ui').style.display = 'none';
|
|
||||||
};
|
|
||||||
|
|
||||||
UI.prototype.updatePhotoStatus = function (msg) {
|
|
||||||
document.getElementById('photos-session-status').innerText = msg;
|
|
||||||
};
|
|
||||||
|
|
||||||
var ui = new UI();
|
var ui = new UI();
|
||||||
window.ui = ui;
|
window.ui = ui;
|
||||||
|
|
||||||
@ -1104,6 +1125,7 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// --- Picker ---
|
||||||
// --- Picker ---
|
// --- Picker ---
|
||||||
openPicker() {
|
openPicker() {
|
||||||
if (!pickerApiLoaded) return alert("API Loading...");
|
if (!pickerApiLoaded) return alert("API Loading...");
|
||||||
@ -1116,7 +1138,7 @@
|
|||||||
.importFromPicker(state.sku, fileId, mime, name, url);
|
.importFromPicker(state.sku, fileId, mime, name, url);
|
||||||
},
|
},
|
||||||
|
|
||||||
// --- Photos ---
|
// --- Photos (Popup Flow) ---
|
||||||
startPhotoSession() {
|
startPhotoSession() {
|
||||||
ui.updatePhotoStatus("Starting session...");
|
ui.updatePhotoStatus("Starting session...");
|
||||||
google.script.run
|
google.script.run
|
||||||
@ -1165,7 +1187,11 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// --- Legacy Photos Session (Removed in favor of Embedded Picker) ---
|
||||||
|
// startPhotoSession() { ... }
|
||||||
|
|
||||||
// --- Compatibility / Matching Logic ---
|
// --- Compatibility / Matching Logic ---
|
||||||
|
|
||||||
matches: [],
|
matches: [],
|
||||||
currentMatchIndex: 0,
|
currentMatchIndex: 0,
|
||||||
hasRunMatching: false,
|
hasRunMatching: false,
|
||||||
@ -1319,18 +1345,20 @@
|
|||||||
.setMimeTypes("image/png,image/jpeg,image/jpg,video/mp4")
|
.setMimeTypes("image/png,image/jpeg,image/jpg,video/mp4")
|
||||||
.setIncludeFolders(true)
|
.setIncludeFolders(true)
|
||||||
.setSelectFolderEnabled(false);
|
.setSelectFolderEnabled(false);
|
||||||
const photosView = new google.picker.PhotosView();
|
|
||||||
|
|
||||||
new google.picker.PickerBuilder()
|
const builder = new google.picker.PickerBuilder();
|
||||||
.addView(view)
|
|
||||||
.addView(photosView)
|
builder.addView(view)
|
||||||
.setOAuthToken(config.token)
|
.setOAuthToken(config.token)
|
||||||
.setDeveloperKey(config.apiKey)
|
.setDeveloperKey(config.apiKey)
|
||||||
|
.setOrigin(window.location.protocol + '//' + window.location.host)
|
||||||
.setCallback(data => {
|
.setCallback(data => {
|
||||||
if (data.action == google.picker.Action.PICKED) {
|
if (data.action == google.picker.Action.PICKED) {
|
||||||
const doc = data.docs[0];
|
const doc = data.docs[0];
|
||||||
const url = (doc.thumbnails && doc.thumbnails.length > 0) ? doc.thumbnails[doc.thumbnails.length - 1].url : null;
|
const isDrive = doc.serviceId === 'docs';
|
||||||
controller.importFromPicker(doc.id, doc.mimeType, doc.name, url);
|
|
||||||
|
// Drive File (Always, since we removed Photos view)
|
||||||
|
controller.importFromPicker(doc.id, doc.mimeType, doc.name, null);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
"https://www.googleapis.com/auth/script.scriptapp",
|
"https://www.googleapis.com/auth/script.scriptapp",
|
||||||
"https://www.googleapis.com/auth/drive",
|
"https://www.googleapis.com/auth/drive",
|
||||||
"https://www.googleapis.com/auth/userinfo.email",
|
"https://www.googleapis.com/auth/userinfo.email",
|
||||||
"https://www.googleapis.com/auth/photospicker.mediaitems.readonly"
|
"https://www.googleapis.com/auth/photospicker.mediaitems.readonly",
|
||||||
|
"https://www.googleapis.com/auth/drive.photos.readonly"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user