mirror of
https://github.com/HeyPuter/puter.git
synced 2026-04-25 00:38:48 -05:00
Only show Puter Dialog when needed
This commit is contained in:
+26
-3
@@ -829,6 +829,13 @@ window.initgui = async function(options){
|
||||
let headers = {};
|
||||
if(window.custom_headers)
|
||||
headers = window.custom_headers;
|
||||
|
||||
// if this is a popup, show a spinner
|
||||
let spinner_init_ts = Date.now();
|
||||
if(window.embedded_in_popup){
|
||||
puter.ui.showSpinner('Setting up your <a href="https://puter.com" target="_blank">Puter</a> account for secure AI and Cloud features...');
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: window.gui_origin + "/signup",
|
||||
type: 'POST',
|
||||
@@ -841,18 +848,34 @@ window.initgui = async function(options){
|
||||
is_temp: true,
|
||||
}),
|
||||
success: async function (data){
|
||||
window.update_auth_data(data.token, data.user);
|
||||
document.dispatchEvent(new Event("login", { bubbles: true}));
|
||||
// if this is a popup, hide the spinner, make sure it was visible for at least 2 seconds
|
||||
if(window.embedded_in_popup){
|
||||
let spinner_duration = (Date.now() - spinner_init_ts);
|
||||
setTimeout(() => {
|
||||
window.update_auth_data(data.token, data.user);
|
||||
document.dispatchEvent(new Event("login", { bubbles: true}));
|
||||
puter.ui.hideSpinner();
|
||||
}, spinner_duration > 2000 ? 10 : 2000 - spinner_duration);
|
||||
|
||||
return;
|
||||
}else{
|
||||
window.update_auth_data(data.token, data.user);
|
||||
document.dispatchEvent(new Event("login", { bubbles: true}));
|
||||
}
|
||||
},
|
||||
error: async (err) => {
|
||||
UIAlert({
|
||||
message: html_encode(err.responseText),
|
||||
});
|
||||
},
|
||||
complete: function(){
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// if there is at least one window open (only non-Explorer windows), ask user for confirmation when navigating away
|
||||
// if there is at least one window open (only non-Explorer windows), ask user for confirmation when navigating away from puter
|
||||
if(window.feature_flags.prompt_user_when_navigation_away_from_puter){
|
||||
window.onbeforeunload = function(){
|
||||
if($(`.window:not(.window[data-app="explorer"])`).length > 0)
|
||||
|
||||
@@ -520,7 +520,21 @@ export default window.puter = (function() {
|
||||
}
|
||||
|
||||
print = function(...args){
|
||||
// Check if the last argument is an options object with escapeHTML property
|
||||
let options = {};
|
||||
if(args.length > 0 && typeof args[args.length - 1] === 'object' && args[args.length - 1] !== null && 'escapeHTML' in args[args.length - 1]) {
|
||||
options = args.pop();
|
||||
}
|
||||
|
||||
for(let arg of args){
|
||||
// Escape HTML if the option is set to true
|
||||
if(options.escapeHTML === true && typeof arg === 'string') {
|
||||
arg = arg.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''');
|
||||
}
|
||||
document.body.innerHTML += arg;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,10 +10,58 @@ class PuterDialog extends HTMLElement {
|
||||
|
||||
constructor(resolve, reject) {
|
||||
super();
|
||||
this.attachShadow({ mode: 'open' });
|
||||
|
||||
this.reject = reject;
|
||||
this.resolve = resolve;
|
||||
this.popupLaunched = false; // Track if popup was successfully launched
|
||||
|
||||
/**
|
||||
* Detects if there's a recent user activation that would allow popup opening
|
||||
* @returns {boolean} True if user activation is available, false otherwise.
|
||||
*/
|
||||
this.hasUserActivation = () => {
|
||||
// Modern browsers support navigator.userActivation
|
||||
if (navigator.userActivation) {
|
||||
return navigator.userActivation.hasBeenActive && navigator.userActivation.isActive;
|
||||
}
|
||||
|
||||
// Fallback: try to detect user activation by attempting to open a popup
|
||||
// This is a bit hacky but works as a fallback
|
||||
try {
|
||||
const testPopup = window.open('', '_blank', 'width=1,height=1,left=-1000,top=-1000');
|
||||
if (testPopup) {
|
||||
testPopup.close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Launches the authentication popup window
|
||||
* @returns {Window|null} The popup window reference or null if failed
|
||||
*/
|
||||
this.launchPopup = () => {
|
||||
try {
|
||||
let w = 600;
|
||||
let h = 400;
|
||||
let title = 'Puter';
|
||||
var left = (screen.width/2)-(w/2);
|
||||
var top = (screen.height/2)-(h/2);
|
||||
const popup = window.open(
|
||||
puter.defaultGUIOrigin + '/?embedded_in_popup=true&request_auth=true' + (window.crossOriginIsolated ? '&cross_origin_isolated=true' : ''),
|
||||
title,
|
||||
'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width='+w+', height='+h+', top='+top+', left='+left
|
||||
);
|
||||
return popup;
|
||||
} catch (e) {
|
||||
console.error('Failed to open popup:', e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
this.attachShadow({ mode: 'open' });
|
||||
|
||||
let h;
|
||||
// Dialog
|
||||
@@ -408,7 +456,20 @@ class PuterDialog extends HTMLElement {
|
||||
}
|
||||
|
||||
open() {
|
||||
this.shadowRoot.querySelector('dialog').showModal();
|
||||
console.log(this.hasUserActivation());
|
||||
if(this.hasUserActivation()){
|
||||
let w = 600;
|
||||
let h = 400;
|
||||
let title = 'Puter';
|
||||
var left = (screen.width/2)-(w/2);
|
||||
var top = (screen.height/2)-(h/2);
|
||||
window.open(puter.defaultGUIOrigin + '/?embedded_in_popup=true&request_auth=true' + (window.crossOriginIsolated ? '&cross_origin_isolated=true' : ''),
|
||||
title,
|
||||
'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width='+w+', height='+h+', top='+top+', left='+left);
|
||||
}
|
||||
else{
|
||||
this.shadowRoot.querySelector('dialog').showModal();
|
||||
}
|
||||
}
|
||||
|
||||
close() {
|
||||
|
||||
@@ -1307,7 +1307,7 @@ class UI extends EventListener {
|
||||
#showTime = null;
|
||||
#hideTimeout = null;
|
||||
|
||||
showSpinner() {
|
||||
showSpinner(html) {
|
||||
if (this.#overlayActive) return;
|
||||
|
||||
// Create and add stylesheet for spinner if it doesn't exist
|
||||
@@ -1330,6 +1330,7 @@ class UI extends EventListener {
|
||||
font-size: 16px;
|
||||
margin-top: 10px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
@@ -1342,10 +1343,11 @@ class UI extends EventListener {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
min-height: 120px;
|
||||
background: #ffffff;
|
||||
border-radius: 10px;
|
||||
padding: 20px;
|
||||
min-width: 120px;
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(styleSheet);
|
||||
@@ -1377,7 +1379,7 @@ class UI extends EventListener {
|
||||
// Add spinner and text
|
||||
container.innerHTML = `
|
||||
<div class="puter-loading-spinner"></div>
|
||||
<div class="puter-loading-text">Working...</div>
|
||||
<div class="puter-loading-text">${html ?? 'Working...'}</div>
|
||||
`;
|
||||
|
||||
overlay.appendChild(container);
|
||||
|
||||
Reference in New Issue
Block a user