diff --git a/src/dev-center/js/apps.js b/src/dev-center/js/apps.js index 2be245f5b..39dae8cb6 100644 --- a/src/dev-center/js/apps.js +++ b/src/dev-center/js/apps.js @@ -191,6 +191,9 @@ async function create_app (title, source_path = null, items = null) { maximizeOnStart: false, background: false, dedupeName: true, + // New apps accept user feedback by default; developers can turn this + // off in the app's settings (the "User Feedback" toggle). + feedbackEnabled: true, metadata: { window_resizable: true, fullpage_on_landing: true, @@ -509,6 +512,12 @@ function generate_edit_app_section (app) {

Misc

+
+ + +

When enabled, users can send you feedback about this app from within Puter. Feedback is delivered to your account's email address.

+
+
@@ -586,6 +595,7 @@ function trackOriginalValues () { locked: $('#edit-app-locked').is(':checked'), fullPageOnLanding: $('#edit-app-fullpage-on-landing').is(':checked'), setTitleToFile: $('#edit-app-set-title-to-file').is(':checked'), + userFeedback: $('#edit-app-user-feedback').is(':checked'), }, }; } @@ -626,7 +636,8 @@ function hasChanges () { $('#edit-app-hide-titlebar').is(':checked') !== originalValues.checkboxes.hideTitleBar || $('#edit-app-locked').is(':checked') !== originalValues.checkboxes.locked || $('#edit-app-fullpage-on-landing').is(':checked') !== originalValues.checkboxes.fullPageOnLanding || - $('#edit-app-set-title-to-file').is(':checked') !== originalValues.checkboxes.setTitleToFile + $('#edit-app-set-title-to-file').is(':checked') !== originalValues.checkboxes.setTitleToFile || + $('#edit-app-user-feedback').is(':checked') !== originalValues.checkboxes.userFeedback ); } @@ -674,6 +685,7 @@ function resetToOriginalValues () { $('#edit-app-locked').prop('checked', originalValues.checkboxes.locked); $('#edit-app-fullpage-on-landing').prop('checked', originalValues.checkboxes.fullPageOnLanding); $('#edit-app-set-title-to-file').prop('checked', originalValues.checkboxes.setTitleToFile); + $('#edit-app-user-feedback').prop('checked', originalValues.checkboxes.userFeedback); if ( originalValues.icon ) { $('#edit-app-icon').css('background-image', `url(${originalValues.icon})`); @@ -1284,6 +1296,7 @@ async function saveEditedApp (mode) { description: description, maximizeOnStart: $('#edit-app-maximize-on-start').is(':checked'), background: $('#edit-app-background').is(':checked'), + feedbackEnabled: $('#edit-app-user-feedback').is(':checked'), metadata: { fullpage_on_landing: $('#edit-app-fullpage-on-landing').is(':checked'), social_image: socialImageUrl, diff --git a/src/puter-js/tests/api/suites/apps.suite.ts b/src/puter-js/tests/api/suites/apps.suite.ts index 12aa6a805..8ee2e0e26 100644 --- a/src/puter-js/tests/api/suites/apps.suite.ts +++ b/src/puter-js/tests/api/suites/apps.suite.ts @@ -144,6 +144,28 @@ export default suite('apps', { t.assert.equal(updated.description, 'New description'); }, + 'feedbackEnabled round-trips on create and survives an unrelated update': + async (t) => { + // Mirrors Dev Center: create with feedback on, then a Save-style + // update that omits feedbackEnabled must not clear it. + const created = await t.puter.apps.create({ + name: 'apps-suite-feedback', + indexURL: 'https://example.com/feedback', + feedbackEnabled: true, + }); + t.assert.equal(Boolean(created.feedback_enabled), true); + + const updated = await t.puter.apps.update('apps-suite-feedback', { + title: 'Feedback App', + }); + t.assert.equal(Boolean(updated.feedback_enabled), true); + + const disabled = await t.puter.apps.update('apps-suite-feedback', { + feedbackEnabled: false, + }); + t.assert.equal(Boolean(disabled.feedback_enabled), false); + }, + 'get of an unknown app rejects': async (t) => { await t.assert.rejects( () => t.puter.apps.get('apps-suite-does-not-exist'),