Skip to content

tweak: add cancel button to deploy dev center #1243

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 73 additions & 111 deletions src/dev-center/js/dev-center.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ let dropped_items;
let search_query;
let originalValues = {};

// At the top of your file, add a global variable to track deployment cancellation
let globalDeploymentCancelled = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can probably just call this deploymentCancelled, since there's no "local deployment" option in the dev center.


const APP_CATEGORIES = [
{ id: 'games', label: 'Games' },
{ id: 'developer-tools', label: 'Developer Tools' },
Expand Down Expand Up @@ -526,7 +529,7 @@ function generate_edit_app_section(app) {
<button class="deploy-btn disable-user-select button button-primary disabled">Deploy Now</button>
</div>

<div class="section-tab" data-tab="info">
<div class="section-tab" data-tab="info">x
<form style="clear:both; padding-bottom: 50px;">
<div class="error" id="edit-app-error"></div>
<div class="success" id="edit-app-success">App has been successfully updated.<span class="close-success-msg">&times;</span>
Expand Down Expand Up @@ -569,8 +572,7 @@ function generate_edit_app_section(app) {

<label for="edit-app-filetype-associations">File Associations</label>
<p style="margin-top: 10px; font-size:13px;">A list of file type specifiers. For example if you include <code>.txt</code> your apps could be opened when a user clicks on a TXT file.</p>
<p style="margin-top: 5px; font-size:13px;">You can paste multiple extensions at once (comma, space, or tab separated) or press comma to add each extension.</p>
<textarea id="edit-app-filetype-associations" placeholder="Paste multiple extensions like: .txt, .doc, .pdf, application/json">${JSON.stringify(app.filetype_associations.map(item => ({ "value": item })), null, app.filetype_associations.length).replace(/</g, '\\u003c')}</textarea>
<textarea id="edit-app-filetype-associations" placeholder=".txt .jpg application/json">${JSON.stringify(app.filetype_associations.map(item => ({ "value": item })), null, app.filetype_associations.length)}</textarea>

<h3 style="font-size: 23px; border-bottom: 1px solid #EEE; margin-top: 50px; margin-bottom: 0px;">Window</h3>
<div>
Expand Down Expand Up @@ -817,8 +819,7 @@ async function edit_app_section(cur_app_name, tab = 'deploy') {
const filetype_association_input = document.querySelector('textarea[id=edit-app-filetype-associations]');
let tagify = new Tagify(filetype_association_input, {
pattern: /\.(?:[a-z0-9]+)|(?:[a-z]+\/(?:[a-z0-9.-]+|\*))/,
delimiters: ",", // Use comma as delimiter
duplicates: false, // Prevent duplicate tags
delimiters: ", ",
enforceWhitelist: false,
dropdown : {
// show the dropdown immediately on focus (0 character typed)
Expand Down Expand Up @@ -1074,101 +1075,7 @@ async function edit_app_section(cur_app_name, tab = 'deploy') {
// Focus on the first input
$('#edit-app-title').focus();

try {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a comment about why this section of code was removed?

activate_tippy();
} catch (e) {
console.log('no tippy:', e);
}

// Custom function to handle bulk pasting of file extensions
if (tagify) {
// Create a completely separate paste handler
const handleBulkPaste = function(e) {
const clipboardData = e.clipboardData || window.clipboardData;
if (!clipboardData) return;

const pastedText = clipboardData.getData('text');
if (!pastedText) return;

// Check if the pasted text contains delimiters
if (/[,;\t\s]/.test(pastedText)) {
e.stopPropagation();
e.preventDefault();

// Process the pasted text to extract extensions
const extensions = pastedText.split(/[,;\t\s]+/)
.map(ext => ext.trim())
.filter(ext => ext && (ext.startsWith('.') || ext.includes('/')));

if (extensions.length > 0) {
// Get existing values to prevent duplicates
const existingValues = tagify.value.map(tag => tag.value);

// Only add extensions that don't already exist
const newExtensions = extensions.filter(ext => !existingValues.includes(ext));

if (newExtensions.length > 0) {
// Add the new tags
tagify.addTags(newExtensions);

// Update the UI
setTimeout(() => {
toggleSaveButton();
toggleResetButton();
}, 10);
}
}

// Clear the input element to prevent any text concatenation
setTimeout(() => {
if (tagify.DOM.input) {
tagify.DOM.input.textContent = '';
}
}, 10);
}
};

// Add the paste handler directly to the tagify wrapper element
const tagifyWrapper = tagify.DOM.scope;
if (tagifyWrapper) {
tagifyWrapper.addEventListener('paste', handleBulkPaste, true);
}

// Also add it to the input element for better coverage
if (tagify.DOM.input) {
tagify.DOM.input.addEventListener('paste', handleBulkPaste, true);
}

// Add a comma key handler to support adding tags with comma
tagify.DOM.input.addEventListener('keydown', function(e) {
if (e.key === ',' && tagify.DOM.input.textContent.trim()) {
e.preventDefault();

const text = tagify.DOM.input.textContent.trim();

// Only add valid extensions
if ((text.startsWith('.') || text.includes('/')) &&
tagify.settings.pattern.test(text)) {

// Check for duplicates
const existingValues = tagify.value.map(tag => tag.value);

if (!existingValues.includes(text)) {
tagify.addTags([text]);

// Update UI
setTimeout(() => {
toggleSaveButton();
toggleResetButton();
}, 10);
}

// Always clear the input
tagify.DOM.input.textContent = '';
}
}
});
}
activate_tippy();
}

$('.jip-submit-btn').on('click', async function (e) {
Expand Down Expand Up @@ -1485,6 +1392,7 @@ $(document).on('click', '.delete-app-settings', async function (e) {
},
// make sure the modal was shown for at least 2 seconds
(Date.now() - init_ts) > 2000 ? 1 : 2000 - (Date.now() - init_ts));

// get app directory
puter.fs.stat({
path: `/${authUsername}/AppData/${dev_center_uid}/${app_uid}`,
Expand All @@ -1507,7 +1415,8 @@ $(document).on('click', '.delete-app-settings', async function (e) {
},
]);
},
(Date.now() - init_ts) > 2000 ? 1 : (2000 - (Date.now() - init_ts)));
// make sure the modal was shown for at least 2 seconds
(Date.now() - init_ts) > 2000 ? 1 : 2000 - (Date.now() - init_ts));
})
}
})
Expand Down Expand Up @@ -1971,6 +1880,41 @@ async function showGitWarningDialog() {
}

window.deploy = async function (app, items) {
// Reset the global cancellation flag at the start of each deployment
globalDeploymentCancelled = false;

// Show deploying spinner with cancel button
$('.drop-area').html(`
${deploying_spinner}
<div>Deploying <span class="deploy-percent">(0%)</span></div>
<br>
<div class="cancel-deployment-btn" style="cursor:pointer; display:inline-block; z-index:10000; padding:5px 10px; border:1px solid #ccc; background:#f0f0f0; margin-top:10px;">Cancel Deployment</div>
`);

// Add event listener with immediate visual feedback
$('.cancel-deployment-btn').on('click', function() {
console.log('Cancel button clicked!');
alert('Cancellation requested!'); // This will verify if the click is being detected

// Provide immediate visual feedback
$(this).prop('disabled', true).text('Cancelling...');

// Set a global cancellation flag
window.deploymentCancelled = true;

// Reset the UI after a brief delay
setTimeout(function() {
reset_drop_area();
puter.ui.notify('Deployment cancelled');
}, 500);
});

// Throughout the deploy function, add these checks FREQUENTLY:
if (globalDeploymentCancelled) {
console.log('Deployment was cancelled, exiting function');
return;
}

// Check for .git directory before proceeding
try {
if (await hasGitDirectory(items)) {
Expand All @@ -1989,12 +1933,6 @@ window.deploy = async function (app, items) {
$('.deploy-btn').addClass('disabled');

// change drop area text
$('.drop-area').html(deploying_spinner + ' <div>Deploying <span class="deploy-percent">(0%)</span></div>');

if (typeof items === 'string' && (items.startsWith('/') || items.startsWith('~'))) {
$('.drop-area').removeClass('drop-area-hover');
$('.drop-area').addClass('drop-area-ready-to-deploy');
}

// --------------------------------------------------------------------
// Get current directory, we need to delete the existing hostname
Expand Down Expand Up @@ -2203,6 +2141,12 @@ window.deploy = async function (app, items) {
})
})
}

// Near the end of the function
if (!globalDeploymentCancelled) {
// Only finalize deployment if not cancelled
// ... update the app URL, etc.
}
}

$(document).on('click', '.section-tab-btn', function (e) {
Expand Down Expand Up @@ -2411,10 +2355,16 @@ $(document).on('click', '.add-app-to-desktop', function (e) {
})

function reset_drop_area() {
dropped_items = null;
$('.drop-area').html(drop_area_placeholder);
// ... existing code ...

// Make sure to reset any UI elements associated with deployment
$('.drop-area').removeClass('drop-area-ready-to-deploy');
$('.deploy-btn').addClass('disabled');
$('.drop-area').removeClass('drop-area-hover');

// Reset to original drop area content
$('.drop-area').html(`<p>Drag and drop files or a directory here</p><p>or</p><p><button class="browse-files-btn">Browse Files</button></p>`);

// ... any other cleanup needed
}

$('body').on('dragover', function (event) {
Expand Down Expand Up @@ -3062,4 +3012,16 @@ function activate_tippy(){
placement: 'top',
arrow: true,
});
}
}

// Add this outside the deploy function, with your other event handlers
$(document).on('click', '.reset-deploy span', function() {
// Reset the drop area to its original state
reset_drop_area();

// Clear the dropped items
dropped_items = [];

// Disable the deploy button
$('.deploy-btn').addClass('disabled');
});