From 36de2b9aa4e0fea8350dac67956d4ea856ecf75c Mon Sep 17 00:00:00 2001 From: Nariman Jelveh Date: Mon, 4 May 2026 14:11:56 -0700 Subject: [PATCH] Remove settings UI & service; redirect to dashboard (#2900) --- src/gui/src/UI/Settings/UITabAbout.js | 117 ----------- src/gui/src/UI/Settings/UITabAccount.js | 171 --------------- .../src/UI/Settings/UITabKeyboardShortcuts.js | 132 ------------ src/gui/src/UI/Settings/UITabLanguage.js | 83 -------- .../src/UI/Settings/UITabPersonalization.js | 79 ------- src/gui/src/UI/Settings/UITabSecurity.js | 96 --------- src/gui/src/UI/Settings/UITabUsage.js | 191 ----------------- src/gui/src/UI/Settings/UIWindowSettings.js | 195 ------------------ src/gui/src/UI/UIDesktop.js | 13 +- src/gui/src/initgui.js | 2 - src/gui/src/keyboard.js | 3 +- src/gui/src/services/SettingsService.js | 64 ------ 12 files changed, 4 insertions(+), 1142 deletions(-) delete mode 100644 src/gui/src/UI/Settings/UITabAbout.js delete mode 100644 src/gui/src/UI/Settings/UITabAccount.js delete mode 100644 src/gui/src/UI/Settings/UITabKeyboardShortcuts.js delete mode 100644 src/gui/src/UI/Settings/UITabLanguage.js delete mode 100644 src/gui/src/UI/Settings/UITabPersonalization.js delete mode 100644 src/gui/src/UI/Settings/UITabSecurity.js delete mode 100644 src/gui/src/UI/Settings/UITabUsage.js delete mode 100644 src/gui/src/UI/Settings/UIWindowSettings.js delete mode 100644 src/gui/src/services/SettingsService.js diff --git a/src/gui/src/UI/Settings/UITabAbout.js b/src/gui/src/UI/Settings/UITabAbout.js deleted file mode 100644 index 2b0682dcd..000000000 --- a/src/gui/src/UI/Settings/UITabAbout.js +++ /dev/null @@ -1,117 +0,0 @@ -/** - * Copyright (C) 2024-present Puter Technologies Inc. - * - * This file is part of Puter. - * - * Puter is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -// About -export default { - id: 'about', - title_i18n_key: 'about', - icon: 'logo-outline.svg', - html: () => { - return ` -
-
- -

${i18n('puter_description')}

- - -
-
- - -
-

${i18n('oss_code_and_content')}

-
- -
-
-
-
`; - }, - init: ($el_window) => { - // server and version infomration - puter.os.version() - .then(res => { - const deployed_date = new Date(res.deploy_timestamp).toLocaleString(); - $el_window.find('.version').html(`Version: ${html_encode(res.version)} • Server: ${html_encode(res.location)} • Deployed: ${html_encode(deployed_date)}`); - }) - .catch(error => { - console.error('Failed to fetch server info:', error); - $el_window.find('.version').html('Failed to load version information.'); - }); - - $el_window.find('.credits').on('click', function (e) { - if ( $(e.target).hasClass('credits') ) { - $('.credits').get(0).close(); - } - }); - - $el_window.find('.show-credits').on('click', function (e) { - $('.credits').get(0).showModal(); - }); - - }, -}; diff --git a/src/gui/src/UI/Settings/UITabAccount.js b/src/gui/src/UI/Settings/UITabAccount.js deleted file mode 100644 index 5fad518f5..000000000 --- a/src/gui/src/UI/Settings/UITabAccount.js +++ /dev/null @@ -1,171 +0,0 @@ -/** - * Copyright (C) 2024-present Puter Technologies Inc. - * - * This file is part of Puter. - * - * Puter is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import UIWindowChangePassword from '../UIWindowChangePassword.js'; -import UIWindowChangeEmail from './UIWindowChangeEmail.js'; -import UIWindowChangeUsername from '../UIWindowChangeUsername.js'; -import UIWindowConfirmUserDeletion from './UIWindowConfirmUserDeletion.js'; -import UIWindowManageSessions from '../UIWindowManageSessions.js'; -import UIWindow from '../UIWindow.js'; - -// About -export default { - id: 'account', - title_i18n_key: 'account', - icon: 'user.svg', - html: () => { - let h = ''; - // profile picture - h += '
'; - h += `
`; - h += '
'; - h += '
'; - - // change password button - if ( ! window.user.is_temp ) { - h += '
'; - h += `${i18n('password')}`; - h += '
'; - h += ``; - h += '
'; - h += '
'; - } - - // change username button - h += '
'; - h += '
'; - h += `${i18n('username')}`; - h += `${html_encode(window.user.username)}`; - h += '
'; - h += '
'; - h += ``; - h += '
'; - h += '
'; - // change email button - if ( window.user.email ) { - h += '
'; - h += '
'; - h += `${i18n('email')}`; - h += `${html_encode(window.user.email)}`; - h += '
'; - h += '
'; - h += ``; - h += '
'; - h += '
'; - } - // 'Delete Account' button - h += '
'; - h += `${i18n('delete_account')}`; - h += '
'; - h += ``; - h += '
'; - h += '
'; - return h; - }, - init: ($el_window) => { - $el_window.find('.change-password').on('click', function (e) { - UIWindowChangePassword({ - window_options: { - parent_uuid: $el_window.attr('data-element_uuid'), - disable_parent_window: true, - parent_center: true, - }, - }); - }); - $el_window.find('.change-username').on('click', function (e) { - UIWindowChangeUsername({ - window_options: { - parent_uuid: $el_window.attr('data-element_uuid'), - disable_parent_window: true, - parent_center: true, - }, - }); - }); - $el_window.find('.change-email').on('click', function (e) { - UIWindowChangeEmail({ - window_options: { - parent_uuid: $el_window.attr('data-element_uuid'), - disable_parent_window: true, - parent_center: true, - }, - }); - }); - $el_window.find('.manage-sessions').on('click', function (e) { - UIWindowManageSessions({ - window_options: { - parent_uuid: $el_window.attr('data-element_uuid'), - disable_parent_window: true, - parent_center: true, - }, - }); - }); - $el_window.find('.delete-account').on('click', function (e) { - UIWindowConfirmUserDeletion({ - window_options: { - parent_uuid: $el_window.attr('data-element_uuid'), - disable_parent_window: true, - parent_center: true, - }, - }); - }); - $el_window.find('.change-profile-picture').on('click', async function (e) { - // open dialog - UIWindow({ - path: `/${ window.user.username }/Desktop`, - // this is the uuid of the window to which this dialog will return - parent_uuid: $el_window.attr('data-element_uuid'), - allowed_file_types: ['.png', '.jpg', '.jpeg'], - show_maximize_button: false, - show_minimize_button: false, - title: 'Open', - is_dir: true, - is_openFileDialog: true, - selectable_body: false, - }); - }); - $el_window.on('file_opened', async function (e) { - let selected_file = Array.isArray(e.detail) ? e.detail[0] : e.detail; - // set profile picture - const profile_pic = await puter.fs.read(selected_file.path); - // blob to base64 - const reader = new FileReader(); - reader.readAsDataURL(profile_pic); - reader.onloadend = function () { - // resizes the image to 150x150 - const img = new Image(); - img.src = reader.result; - img.onload = function () { - const canvas = document.createElement('canvas'); - const ctx = canvas.getContext('2d'); - canvas.width = 150; - canvas.height = 150; - ctx.drawImage(img, 0, 0, 150, 150); - const base64data = canvas.toDataURL('image/png'); - // update profile picture everywhere (matches helpers.js session refresh) - $el_window.find('.profile-picture').css('background-image', `url(${ html_encode(base64data) })`); - $('.profile-pic').css('background-image', `url(${ html_encode(base64data) })`); - $('.profile-image').css('background-image', `url(${ html_encode(base64data) })`); - $('.profile-image').addClass('profile-image-has-picture'); - // update profile picture - update_profile(window.user.username, { picture: base64data }); - }; - }; - }); - }, -}; diff --git a/src/gui/src/UI/Settings/UITabKeyboardShortcuts.js b/src/gui/src/UI/Settings/UITabKeyboardShortcuts.js deleted file mode 100644 index 3f178adab..000000000 --- a/src/gui/src/UI/Settings/UITabKeyboardShortcuts.js +++ /dev/null @@ -1,132 +0,0 @@ -/** - * Copyright (C) 2024-present Puter Technologies Inc. - * - * This file is part of Puter. - * - * Puter is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -const shortcutSections = () => ([ - { - title: i18n('keyboard_shortcuts_general'), - rows: [ - { - action: i18n('keyboard_shortcuts_open_help'), - keys: 'F1 / Ctrl+?', - }, - { - action: i18n('keyboard_shortcuts_search'), - keys: 'Ctrl/Cmd + F', - }, - { - action: i18n('keyboard_shortcuts_close_window'), - keys: 'Ctrl + W', - }, - { - action: i18n('keyboard_shortcuts_undo'), - keys: 'Ctrl/Cmd + Z', - }, - { - action: i18n('keyboard_shortcuts_select_all'), - keys: 'Ctrl/Cmd + A', - }, - { - action: i18n('keyboard_shortcuts_open_item'), - keys: 'Enter', - }, - { - action: i18n('keyboard_shortcuts_close_menus'), - keys: 'Esc', - }, - ], - }, - { - title: i18n('keyboard_shortcuts_navigation'), - rows: [ - { - action: i18n('keyboard_shortcuts_arrow_navigation'), - keys: 'Arrow Keys', - }, - { - action: i18n('keyboard_shortcuts_type_to_select'), - keys: i18n('keyboard_shortcuts_type_to_select_keys'), - }, - ], - }, - { - title: i18n('keyboard_shortcuts_files'), - rows: [ - { - action: i18n('keyboard_shortcuts_copy'), - keys: 'Ctrl/Cmd + C', - }, - { - action: i18n('keyboard_shortcuts_cut'), - keys: 'Ctrl/Cmd + X', - }, - { - action: i18n('keyboard_shortcuts_paste'), - keys: 'Ctrl/Cmd + V', - }, - { - action: i18n('keyboard_shortcuts_delete'), - keys: 'Delete (Win/Linux) / Cmd + Backspace (Mac)', - }, - { - action: i18n('keyboard_shortcuts_permanent_delete'), - keys: 'Shift + Delete (Win/Linux) / Option + Cmd + Backspace (Mac)', - }, - ], - }, -]); - -export default { - id: 'keyboard-shortcuts', - title_i18n_key: 'keyboard_shortcuts', - icon: 'shortcut.svg', - html: () => { - const sections = shortcutSections(); - const sectionHtml = sections.map(section => { - const rows = section.rows.map(row => ` - - ${row.action} - ${row.keys} - - `).join(''); - - return ` -
-

${section.title}

- - - - - - - - - ${rows} - -
${i18n('keyboard_shortcuts_action')}${i18n('keyboard_shortcuts_shortcut')}
-
- `; - }).join(''); - - return ` -

${i18n('keyboard_shortcuts')}

-

${i18n('keyboard_shortcuts_intro')}

- ${sectionHtml} - `; - }, -}; diff --git a/src/gui/src/UI/Settings/UITabLanguage.js b/src/gui/src/UI/Settings/UITabLanguage.js deleted file mode 100644 index 0d219d93e..000000000 --- a/src/gui/src/UI/Settings/UITabLanguage.js +++ /dev/null @@ -1,83 +0,0 @@ -/** - * Copyright (C) 2024-present Puter Technologies Inc. - * - * This file is part of Puter. - * - * Puter is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import changeLanguage from '../../i18n/i18nChangeLanguage.js'; - -// About -export default { - id: 'language', - title_i18n_key: 'language', - icon: 'language.svg', - html: () => { - let h = `

${i18n('language')}

`; - - // search - h += `
- -
`; - - // list of languages - const available_languages = window.listSupportedLanguages(); - h += '
'; - for ( let lang of available_languages ) { - h += `
${html_encode(lang.name)}
`; - } - h += '
'; - return h; - }, - init: ($el_window) => { - $el_window.on('click', '.language-item', function () { - const $this = $(this); - const lang = $this.attr('data-lang'); - changeLanguage(lang); - $this.siblings().removeClass('active'); - $this.addClass('active'); - // make sure all other language items are visible - $this.closest('.language-list').find('.language-item').show(); - }); - - $el_window.on('input', '.search-language', function () { - const $this = $(this); - const search = $this.val().toLowerCase(); - const $container = $this.closest('.settings').find('.settings-content-container'); - const $content = $container.find('.settings-content.active'); - const $list = $content.find('.language-list'); - const $items = $list.find('.language-item'); - $items.each(function () { - const $item = $(this); - const lang = $item.attr('data-lang'); - const name = $item.text().toLowerCase(); - const english_name = $item.attr('data-english-name').toLowerCase(); - if ( name.includes(search) || lang.includes(search) || english_name.includes(search) ) { - $item.show(); - } else { - $item.hide(); - } - }); - }); - }, - on_show: ($content) => { - // Focus on search - $content.find('.search').first().focus(); - // make sure all language items are visible - $content.find('.language-item').show(); - // empty search - $content.find('.search').val(''); - }, -}; diff --git a/src/gui/src/UI/Settings/UITabPersonalization.js b/src/gui/src/UI/Settings/UITabPersonalization.js deleted file mode 100644 index cb58d9925..000000000 --- a/src/gui/src/UI/Settings/UITabPersonalization.js +++ /dev/null @@ -1,79 +0,0 @@ -/** - * Copyright (C) 2024-present Puter Technologies Inc. - * - * This file is part of Puter. - * - * Puter is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import UIWindowThemeDialog from '../UIWindowThemeDialog.js'; -import UIWindowDesktopBGSettings from '../UIWindowDesktopBGSettings.js'; - -// About -export default { - id: 'personalization', - title_i18n_key: 'personalization', - icon: 'palette-outline.svg', - html: () => { - return ` -

${i18n('personalization')}

-
- ${i18n('background')} -
- -
-
-
- ${i18n('ui_colors')} -
- -
-
-
- ${i18n('clock_visibility')} - -
- `; - }, - init: ($el_window) => { - $el_window.find('.change-ui-colors').on('click', function (e) { - UIWindowThemeDialog({ - window_options: { - parent_uuid: $el_window.attr('data-element_uuid'), - disable_parent_window: true, - parent_center: true, - }, - }); - }); - $el_window.find('.change-background').on('click', function (e) { - UIWindowDesktopBGSettings({ - window_options: { - parent_uuid: $el_window.attr('data-element_uuid'), - disable_parent_window: true, - parent_center: true, - }, - }); - }); - - $el_window.on('change', 'select.change-clock-visible', function (e) { - window.change_clock_visible(this.value); - }); - - window.change_clock_visible(); - }, -}; diff --git a/src/gui/src/UI/Settings/UITabSecurity.js b/src/gui/src/UI/Settings/UITabSecurity.js deleted file mode 100644 index 342a3e960..000000000 --- a/src/gui/src/UI/Settings/UITabSecurity.js +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2024-present Puter Technologies Inc. - * - * This file is part of Puter. - * - * Puter is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -import UIWindow2FASetup from '../UIWindow2FASetup.js'; -import UIWindowDisable2FA from './UIWindowDisable2FA.js'; - -export default { - id: 'security', - title_i18n_key: 'security', - icon: 'shield.svg', - html: () => { - let h = `

${i18n('security')}

`; - let user = window.user; - - // change password button - if ( ! user.is_temp ) { - h += '
'; - h += `${i18n('password')}`; - h += '
'; - h += ``; - h += '
'; - h += '
'; - } - - // session manager - h += '
'; - h += `${i18n('sessions')}`; - h += '
'; - h += ``; - h += '
'; - h += '
'; - - // configure 2FA - if ( !user.is_temp && user.email_confirmed ) { - h += `
`; - h += '
'; - h += `${i18n('two_factor')}`; - h += `${ - i18n(user.otp ? 'two_factor_enabled' : 'two_factor_disabled') - }`; - h += '
'; - h += '
'; - h += ``; - h += ``; - h += '
'; - h += '
'; - } - - return h; - }, - init: ($el_window) => { - $el_window.find('.enable-2fa').on('click', async function (e) { - - const { promise } = await UIWindow2FASetup(); - const tfa_was_enabled = await promise; - - if ( tfa_was_enabled ) { - $el_window.find('.enable-2fa').hide(); - $el_window.find('.disable-2fa').show(); - $el_window.find('.user-otp-state').text(i18n('two_factor_enabled')); - $el_window.find('.settings-card-security').removeClass('settings-card-warning'); - $el_window.find('.settings-card-security').addClass('settings-card-success'); - } - - return; - }); - - $el_window.find('.disable-2fa').on('click', async function (e) { - const { promise } = await UIWindowDisable2FA(); - const tfa_was_disabled = await promise; - - if ( tfa_was_disabled ) { - $el_window.find('.enable-2fa').show(); - $el_window.find('.disable-2fa').hide(); - $el_window.find('.user-otp-state').text(i18n('two_factor_disabled')); - $el_window.find('.settings-card-security').removeClass('settings-card-success'); - $el_window.find('.settings-card-security').addClass('settings-card-warning'); - } - }); - }, -}; diff --git a/src/gui/src/UI/Settings/UITabUsage.js b/src/gui/src/UI/Settings/UITabUsage.js deleted file mode 100644 index 7740e7560..000000000 --- a/src/gui/src/UI/Settings/UITabUsage.js +++ /dev/null @@ -1,191 +0,0 @@ -/** - * Copyright (C) 2024-present Puter Technologies Inc. - * - * This file is part of Puter. - * - * Puter is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -// Usage -export default { - id: 'usage', - title_i18n_key: 'usage', - icon: 'speedometer-outline.svg', - html: () => { - return ` -

${i18n('usage')}

-
-
-

${i18n('Storage')}

-
- - used of - - -
-
-
- -
-
-
-
-
-

${i18n('Resources')}

-
- - used of - -
-
-
-
- -
-
- - -
-
`; - }, - init: ($el_window) => { - update_usage_details($el_window); - $($el_window).find('.update-usage-details').on('click', function () { - update_usage_details($el_window); - }); - - // Scoped click handler for usage details toggle - $($el_window).on('click', '.driver-usage-details', function () { - const $container = $(this).closest('.driver-usage'); - $container.find('.driver-usage-details-content').toggleClass('active'); - $(this).toggleClass('active'); - - // change the text of the driver-usage-details-text depending on the class - if ( $(this).hasClass('active') ) { - $(this).find('.driver-usage-details-text').text('Hide usage details'); - } else { - $(this).find('.driver-usage-details-text').text('View usage details'); - } - }); - }, -}; - -async function update_usage_details ($el_window) { - // Add spinning animation and record start time - const startTime = Date.now(); - $($el_window).find('.update-usage-details-icon').css('animation', 'spin 1s linear infinite'); - - const monthlyUsagePromise = puter.auth.getMonthlyUsage().then(res => { - let monthlyAllowance = res.allowanceInfo?.monthUsageAllowance; - let remaining = res.allowanceInfo?.remaining; - let totalUsage = monthlyAllowance - remaining; - let totalUsagePercentage = (totalUsage / monthlyAllowance * 100).toFixed(0); - - $('#total-usage').html(window.number_format(totalUsage / 100_000_000, { decimals: 2, prefix: '$' })); - $('#total-capacity').html(window.number_format(monthlyAllowance / 100_000_000, { decimals: 2, prefix: '$' })); - $('.usage-progbar-percent').html(`${totalUsagePercentage }%`); - $('.usage-progbar').css('width', `${totalUsagePercentage }%`); - - // build the table for the usage details - let h = ''; - - h += ` - - - - - - `; - - h += ''; - for ( let key in res.usage ) { - // value must be object - if ( typeof res.usage[key] !== 'object' ) - { - continue; - } - - // get the units - let units = res.usage[key].units; - - // Bytes should be formatted as human readable - if ( key.startsWith('filesystem:') && key.endsWith(':bytes') ) { - units = window.byte_format(units); - } - // Everything else should be formatted as a number - else { - units = window.number_format(units, { decimals: 0, thousandSeparator: ',' }); - } - - h += ` - - - - - `; - } - h += ''; - h += '
ResourceUnitsCost
${key}${units}${window.number_format(res.usage[key].cost / 100_000_000, { decimals: 2, prefix: '$' })}
'; - - $('.driver-usage-details-content').html(h); - }); - - const spacePromise = puter.fs.space().then(res => { - let usage_percentage = (res.used / res.capacity * 100).toFixed(0); - usage_percentage = usage_percentage > 100 ? 100 : usage_percentage; - - let general_used = res.used; - - let host_usage_percentage = 0; - if ( res.host_used ) { - $('#storage-puter-used').html(window.byte_format(res.used)); - $('#storage-puter-used-w').show(); - - general_used = res.host_used; - host_usage_percentage = ((res.host_used - res.used) / res.capacity * 100).toFixed(0); - } - - $('#storage-used').html(window.byte_format(general_used)); - $('#storage-capacity').html(window.byte_format(res.capacity)); - $('#storage-used-percent').html( - `${usage_percentage }%${ - host_usage_percentage > 0 - ? ` / ${ host_usage_percentage }%` : ''}`); - $('#storage-bar').css('width', `${usage_percentage }%`); - $('#storage-bar-host').css('width', `${host_usage_percentage }%`); - if ( usage_percentage >= 100 ) { - $('#storage-bar').css({ - 'border-top-right-radius': '3px', - 'border-bottom-right-radius': '3px', - }); - } - }); - - // Wait for both promises to complete - await Promise.all([monthlyUsagePromise, spacePromise]); - - // Ensure spinning continues for at least 1 second - const elapsed = Date.now() - startTime; - const minDuration = 1000; // 1 second - if ( elapsed < minDuration ) { - await new Promise(resolve => setTimeout(resolve, minDuration - elapsed)); - } - - // Remove spinning animation - $($el_window).find('.update-usage-details-icon').css('animation', ''); -} \ No newline at end of file diff --git a/src/gui/src/UI/Settings/UIWindowSettings.js b/src/gui/src/UI/Settings/UIWindowSettings.js deleted file mode 100644 index 2f7503666..000000000 --- a/src/gui/src/UI/Settings/UIWindowSettings.js +++ /dev/null @@ -1,195 +0,0 @@ -/** - * Copyright (C) 2024-present Puter Technologies Inc. - * - * This file is part of Puter. - * - * Puter is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import Placeholder from '../../util/Placeholder.js'; -import UIWindow from '../UIWindow.js'; - -def(Symbol('TSettingsTab'), 'ui.traits.TSettingsTab'); - -async function UIWindowSettings (options) { - return new Promise(async (resolve) => { - options = options ?? {}; - - const svc_settings = globalThis.services.get('settings'); - - const tabs = svc_settings.get_tabs(); - const tab_placeholders = []; - - let h = ''; - - h += '
'; - h += '
'; - // sidebar toggle - h += ''; - // sidebar - h += '
'; - // if data-is_fullpage="1" show title saying "Settings" - if ( options.window_options?.is_fullpage ) { - h += `
${i18n('settings')}
`; - } - - // sidebar items - h += `
`; - tabs.forEach((tab, i) => { - h += `
${i18n(tab.title_i18n_key)}
`; - }); - h += '
'; - - // content - h += '
'; - - tabs.forEach((tab, i) => { - h += `
`; - if ( tab.factory || tab.dom ) { - tab_placeholders[i] = Placeholder(); - h += tab_placeholders[i].html; - } else { - h += tab.html(); - } - h += '
'; - }); - - h += '
'; - h += '
'; - h += '
'; - - const el_window = await UIWindow({ - title: 'Settings', - app: 'settings', - single_instance: true, - icon: null, - uid: null, - is_dir: false, - body_content: h, - has_head: true, - selectable_body: false, - allow_context_menu: false, - is_resizable: true, - is_droppable: false, - init_center: true, - allow_native_ctxmenu: true, - allow_user_select: true, - backdrop: false, - width: 800, - height: 'auto', - dominant: true, - show_in_taskbar: false, - draggable_body: false, - onAppend: function (this_window) { - // send event settings-window-opened - window.dispatchEvent(new CustomEvent('settings-window-opened', { detail: { window: this_window } })); - }, - window_class: 'window-settings', - body_css: { - width: 'initial', - height: '100%', - overflow: 'auto', - }, - ...options?.window_options ?? {}, - }); - const $el_window = $(el_window); - tabs.forEach((tab, i) => { - tab.init && tab.init($el_window); - if ( tab.factory ) { - const component = tab.factory(); - component.attach(tab_placeholders[i]); - } - if ( tab.reinitialize ) { - tab.reinitialize(); - } - if ( tab.dom ) { - tab_placeholders[i].replaceWith(tab.dom); - } - }); - - // If options.tab is provided, open that tab - if ( options.tab ) { - const $tabToOpen = $el_window.find(`.settings-sidebar-item[data-settings="${options.tab}"]`); - if ( $tabToOpen.length > 0 ) { - setTimeout(() => { - $tabToOpen.trigger('click'); - }, 50); - } - } - - $(el_window).on('click', '.settings-sidebar-item', function () { - const $this = $(this); - const settings = $this.attr('data-settings'); - const $container = $this.closest('.settings').find('.settings-content-container'); - const $content = $container.find(`.settings-content[data-settings="${settings}"]`); - // add active class to sidebar item - $this.siblings().removeClass('active'); - $this.addClass('active'); - // add active class to content - $container.find('.settings-content').removeClass('active'); - $content.addClass('active'); - - // Run on_show handlers - const tab = tabs.find((tab) => tab.id === settings); - if ( tab?.on_show ) { - tab.on_show($content); - } - }); - - resolve(el_window); - }); -} - -$(document).on('mousedown', '.sidebar-toggle', function (e) { - e.preventDefault(); - $('.settings-sidebar').toggleClass('active'); - $('.sidebar-toggle-button').toggleClass('active'); - // move sidebar toggle button - setTimeout(() => { - $('.sidebar-toggle').css({ - left: $('.settings-sidebar').hasClass('active') ? 243 : 2, - }); - }, 10); -}); - -$(document).on('click', '.settings-sidebar-item', function (e) { - // hide sidebar - $('.settings-sidebar').removeClass('active'); - // move sidebar toggle button ro the right - setTimeout(() => { - $('.sidebar-toggle').css({ - left: 2, - }); - }, 10); - -}); - -// clicking anywhere on the page will close the sidebar -$(document).on('click', function (e) { - // print event target class - - if ( !$(e.target).closest('.settings-sidebar').length && !$(e.target).closest('.sidebar-toggle-button').length && !$(e.target).hasClass('sidebar-toggle-button') && !$(e.target).hasClass('sidebar-toggle') ) { - $('.settings-sidebar').removeClass('active'); - $('.sidebar-toggle-button').removeClass('active'); - // move sidebar toggle button ro the right - setTimeout(() => { - $('.sidebar-toggle').css({ - left: 2, - }); - }, 10); - - } -}); - -export default UIWindowSettings; \ No newline at end of file diff --git a/src/gui/src/UI/UIDesktop.js b/src/gui/src/UI/UIDesktop.js index 1e97cfd90..6c37643b8 100644 --- a/src/gui/src/UI/UIDesktop.js +++ b/src/gui/src/UI/UIDesktop.js @@ -35,7 +35,6 @@ import UITaskbar from './UITaskbar.js'; import new_context_menu_item from '../helpers/new_context_menu_item.js'; import refresh_item_container from '../helpers/refresh_item_container.js'; import changeLanguage from '../i18n/i18nChangeLanguage.js'; -import UIWindowSettings from './Settings/UIWindowSettings.js'; import UIWindowTaskManager from './UIWindowTaskManager.js'; import truncate_filename from '../helpers/truncate_filename.js'; import UINotification from './UINotification.js'; @@ -1296,16 +1295,10 @@ async function UIDesktop (options) { } } //-------------------------------------------------------------------------------------- - // /settings will open settings in fullpage mode + // /settings redirects to /dashboard //-------------------------------------------------------------------------------------- else if ( window.url_paths[0]?.toLocaleLowerCase() === 'settings' ) { - // open settings - UIWindowSettings({ - tab: window.url_paths[1] || 'about', - window_options: { - is_fullpage: true, - }, - }); + window.open('/dashboard', '_blank'); } // --------------------------------------------- // Run apps from insta-login URL @@ -2201,7 +2194,7 @@ $(document).on('click', '.user-options-menu-btn', async function (e) { html: i18n('keyboard_shortcuts'), id: 'keyboard_shortcuts', onClick: async function () { - UIWindowSettings({ tab: 'keyboard-shortcuts' }); + window.open('/dashboard', '_blank'); }, }, //-------------------------------------------------- diff --git a/src/gui/src/initgui.js b/src/gui/src/initgui.js index 5ead48bb8..c0d23a197 100644 --- a/src/gui/src/initgui.js +++ b/src/gui/src/initgui.js @@ -48,7 +48,6 @@ import { IPCService } from './services/IPCService.js'; import { LaunchOnInitService } from './services/LaunchOnInitService.js'; import { LocaleService } from './services/LocaleService.js'; import { ProcessService } from './services/ProcessService.js'; -import { SettingsService } from './services/SettingsService.js'; import { ThemeService } from './services/ThemeService.js'; import { privacy_aware_path } from './util/desktop.js'; @@ -92,7 +91,6 @@ const launch_services = async function (options) { register('theme', new ThemeService()); register('process', new ProcessService()); register('locale', new LocaleService()); - register('settings', new SettingsService()); register('anti-csrf', new AntiCSRFService()); register('__launch-on-init', new LaunchOnInitService()); diff --git a/src/gui/src/keyboard.js b/src/gui/src/keyboard.js index dddb20650..d4df4f761 100644 --- a/src/gui/src/keyboard.js +++ b/src/gui/src/keyboard.js @@ -19,7 +19,6 @@ import UIAlert from './UI/UIAlert.js'; import UIWindowSearch from './UI/UIWindowSearch.js'; -import UIWindowSettings from './UI/Settings/UIWindowSettings.js'; import launch_app from './helpers/launch_app.js'; import open_item from './helpers/open_item.js'; import determine_active_container_parent from './helpers/determine_active_container_parent.js'; @@ -33,7 +32,7 @@ $(document).bind('keydown', async function (e) { if ( e.which === 112 || ((e.ctrlKey || e.metaKey) && e.shiftKey && e.which === 191) ) { e.preventDefault(); e.stopPropagation(); - UIWindowSettings({ tab: 'keyboard-shortcuts' }); + window.open('/dashboard', '_blank'); return false; } //----------------------------------------------------------------------------- diff --git a/src/gui/src/services/SettingsService.js b/src/gui/src/services/SettingsService.js deleted file mode 100644 index 13ee7ac2e..000000000 --- a/src/gui/src/services/SettingsService.js +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2024-present Puter Technologies Inc. - * - * This file is part of Puter. - * - * Puter is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -import { Service } from '../definitions.js'; - -import AboutTab from '../UI/Settings/UITabAbout.js'; -import UsageTab from '../UI/Settings/UITabUsage.js'; -import AccountTab from '../UI/Settings/UITabAccount.js'; -import SecurityTab from '../UI/Settings/UITabSecurity.js'; -import PersonalizationTab from '../UI/Settings/UITabPersonalization.js'; -import LanguageTag from '../UI/Settings/UITabLanguage.js'; -import KeyboardShortcutsTab from '../UI/Settings/UITabKeyboardShortcuts.js'; -import UIElement from '../UI/UIElement.js'; -const TSettingsTab = use('ui.traits.TSettingsTab'); - -export class SettingsService extends Service { - #tabs = []; - async _init () { - ;[ - UsageTab, - AccountTab, - SecurityTab, - PersonalizationTab, - LanguageTag, - KeyboardShortcutsTab, - AboutTab, - ].forEach(tab => { - this.register_tab(tab); - }); - } - get_tabs () { - return this.#tabs; - } - register_tab (tab) { - if ( tab instanceof UIElement ) { - const ui_element = tab; - tab = { - ...ui_element.as(TSettingsTab).get_metadata(), - reinitialize () { - ui_element.reinitialize(); - }, - get dom () { - return ui_element.root; - }, - }; - } - this.#tabs.push(tab); - } -}