From e2f048ec2d5212bfcd8674be4a67bdc535a119ec Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Mon, 15 Apr 2024 16:51:07 +0100 Subject: [PATCH 1/7] Settings: Move 'About'-specific logic and data into UITabAbout.js Keeping all the logic and data for the tab together should make it easier to modify. --- src/UI/Settings/UITabAbout.js | 176 ++++++++++++++++------------ src/UI/Settings/UIWindowSettings.js | 56 ++++----- 2 files changed, 124 insertions(+), 108 deletions(-) diff --git a/src/UI/Settings/UITabAbout.js b/src/UI/Settings/UITabAbout.js index 8ef41dde..8a6631b6 100644 --- a/src/UI/Settings/UITabAbout.js +++ b/src/UI/Settings/UITabAbout.js @@ -18,79 +18,109 @@ */ // About -function UITabAbout(){ - let h = ``; - - h += `
`; - h += `
` - h += `
- -

${i18n('puter_description')}

- - -
-
- - -
-

${i18n('oss_code_and_content')}

-
- +export default { + id: 'about', + title_i18n_key: 'about', + icon: 'logo-outline.svg', + html: () => { + return ` +
+ -
- `; - h += `
`; - h += `
`; +
+ + +
+

${i18n('oss_code_and_content')}

+
+ +
+
+
+ `; + }, + init: ($el_window) => { + // version + $.ajax({ + url: api_origin + "/version", + type: 'GET', + async: true, + contentType: "application/json", + headers: { + "Authorization": "Bearer " + auth_token + }, + statusCode: { + 401: function () { + logout(); + }, + }, + success: function (res) { + var d = new Date(0); + $el_window.find('.version').html('Version: ' + res.version + ' • ' + 'Server: ' + res.location + ' • ' + 'Deployed: ' + new Date(res.deploy_timestamp)); + } + }); - return h; -} -export default UITabAbout; \ No newline at end of file + $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/UI/Settings/UIWindowSettings.js b/src/UI/Settings/UIWindowSettings.js index 1b2c9a23..3073f8b0 100644 --- a/src/UI/Settings/UIWindowSettings.js +++ b/src/UI/Settings/UIWindowSettings.js @@ -23,7 +23,7 @@ import UIWindowChangeEmail from './UIWindowChangeEmail.js' import UIWindowChangeUsername from '../UIWindowChangeUsername.js' import changeLanguage from "../../i18n/i18nChangeLanguage.js" import UIWindowConfirmUserDeletion from './UIWindowConfirmUserDeletion.js'; -import UITabAbout from './UITabAbout.js'; +import AboutTab from './UITabAbout.js'; import UIWindowThemeDialog from '../UIWindowThemeDialog.js'; import UIWindowManageSessions from '../UIWindowManageSessions.js'; @@ -31,13 +31,24 @@ async function UIWindowSettings(options){ return new Promise(async (resolve) => { options = options ?? {}; + const tabs = [ + AboutTab, + // UsageTab, + // AccountTab, + // PersonalizationTab, + // LanguageTab, + // ClockTab, + ]; + let h = ''; h += `
`; h += `
`; // side bar h += `
`; - h += `
${i18n('about')}
`; + tabs.forEach((tab, i) => { + h += `
${i18n(tab.title_i18n_key)}
`; + }); h += `
${i18n('usage')}
`; h += `
${i18n('account')}
`; h += `
${i18n('personalization')}
`; @@ -47,9 +58,12 @@ async function UIWindowSettings(options){ // content h += `
`; - - // About - h += UITabAbout(); + + tabs.forEach((tab, i) => { + h += `
+ ${tab.html()} +
`; + }); // Usage h += `
`; @@ -202,6 +216,8 @@ async function UIWindowSettings(options){ overflow: 'auto' } }); + const $el_window = $(el_window); + tabs.forEach(tab => tab.init($el_window)); $.ajax({ url: api_origin + "/drivers/usage", @@ -300,36 +316,6 @@ async function UIWindowSettings(options){ } }) - // version - $.ajax({ - url: api_origin + "/version", - type: 'GET', - async: true, - contentType: "application/json", - headers: { - "Authorization": "Bearer " + auth_token - }, - statusCode: { - 401: function () { - logout(); - }, - }, - success: function (res) { - var d = new Date(0); - $('.version').html('Version: ' + res.version + ' • ' + 'Server: ' + res.location + ' • ' + 'Deployed: ' + new Date(res.deploy_timestamp)); - } - }) - - $(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(); - }) - $(el_window).find('.change-password').on('click', function (e) { UIWindowChangePassword({ window_options:{ From f5175941d9913d040686be0a6c93fffcb1f965b2 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Mon, 15 Apr 2024 16:51:18 +0100 Subject: [PATCH 2/7] Settings: Move 'Usage' tab into its own file --- src/UI/Settings/UITabUsage.js | 141 ++++++++++++++++++++++++++++ src/UI/Settings/UIWindowSettings.js | 120 +---------------------- 2 files changed, 143 insertions(+), 118 deletions(-) create mode 100644 src/UI/Settings/UITabUsage.js diff --git a/src/UI/Settings/UITabUsage.js b/src/UI/Settings/UITabUsage.js new file mode 100644 index 00000000..88f15b6f --- /dev/null +++ b/src/UI/Settings/UITabUsage.js @@ -0,0 +1,141 @@ +/** + * Copyright (C) 2024 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: 'usage', + title_i18n_key: 'usage', + icon: 'speedometer-outline.svg', + html: () => { + return ` +

Usage

+
+

${i18n('storage_usage')}

+
+ + used of + + +
+
+ +
+
+
+
`; + }, + init: ($el_window) => { + $.ajax({ + url: api_origin + "/drivers/usage", + type: 'GET', + async: true, + contentType: "application/json", + headers: { + "Authorization": "Bearer " + auth_token + }, + statusCode: { + 401: function () { + logout(); + }, + }, + success: function (res) { + let h = ''; // Initialize HTML string for driver usage bars + + // Loop through user services + res.user.forEach(service => { + const { monthly_limit, monthly_usage } = service; + let usageDisplay = ``; + + if (monthly_limit !== null) { + let usage_percentage = (monthly_usage / monthly_limit * 100).toFixed(0); + usage_percentage = usage_percentage > 100 ? 100 : usage_percentage; // Cap at 100% + usageDisplay = ` +
+

${service.service['driver.interface']} (${service.service['driver.method']}):

+ ${monthly_usage} used of ${monthly_limit} +
+
${usage_percentage}%
+
+
+ `; + } + else { + usageDisplay = ` +
+

${service.service['driver.interface']} (${service.service['driver.method']}):

+ ${i18n('usage')}: ${monthly_usage} (${i18n('unlimited')}) +
+ `; + } + h += usageDisplay; + }); + + // Append driver usage bars to the container + $('.settings-content[data-settings="usage"]').append(`
${h}
`); + } + }); + + // df + $.ajax({ + url: api_origin + "/df", + type: 'GET', + async: true, + contentType: "application/json", + headers: { + "Authorization": "Bearer " + auth_token + }, + statusCode: { + 401: function () { + logout(); + }, + }, + success: function (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(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(byte_format(general_used)); + $('#storage-capacity').html(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', + }); + } + } + }); + }, +}; diff --git a/src/UI/Settings/UIWindowSettings.js b/src/UI/Settings/UIWindowSettings.js index 3073f8b0..8758ccac 100644 --- a/src/UI/Settings/UIWindowSettings.js +++ b/src/UI/Settings/UIWindowSettings.js @@ -24,6 +24,7 @@ import UIWindowChangeUsername from '../UIWindowChangeUsername.js' import changeLanguage from "../../i18n/i18nChangeLanguage.js" import UIWindowConfirmUserDeletion from './UIWindowConfirmUserDeletion.js'; import AboutTab from './UITabAbout.js'; +import UsageTab from './UITabUsage.js'; import UIWindowThemeDialog from '../UIWindowThemeDialog.js'; import UIWindowManageSessions from '../UIWindowManageSessions.js'; @@ -33,7 +34,7 @@ async function UIWindowSettings(options){ const tabs = [ AboutTab, - // UsageTab, + UsageTab, // AccountTab, // PersonalizationTab, // LanguageTab, @@ -49,7 +50,6 @@ async function UIWindowSettings(options){ tabs.forEach((tab, i) => { h += `
${i18n(tab.title_i18n_key)}
`; }); - h += `
${i18n('usage')}
`; h += `
${i18n('account')}
`; h += `
${i18n('personalization')}
`; h += `
${i18n('language')}
`; @@ -65,25 +65,6 @@ async function UIWindowSettings(options){
`; }); - // Usage - h += `
`; - h += `

Usage

`; - h += `
-

${i18n('storage_usage')}

-
- - used of - - -
-
- -
-
-
-
` - h += `
`; - // Account h += `
`; h += `

${i18n('account')}

`; @@ -219,103 +200,6 @@ async function UIWindowSettings(options){ const $el_window = $(el_window); tabs.forEach(tab => tab.init($el_window)); - $.ajax({ - url: api_origin + "/drivers/usage", - type: 'GET', - async: true, - contentType: "application/json", - headers: { - "Authorization": "Bearer " + auth_token - }, - statusCode: { - 401: function () { - logout(); - }, - }, - success: function (res) { - let h = ''; // Initialize HTML string for driver usage bars - - // Loop through user services - res.user.forEach(service => { - const { monthly_limit, monthly_usage } = service; - let usageDisplay = ``; - - if (monthly_limit !== null) { - let usage_percentage = (monthly_usage / monthly_limit * 100).toFixed(0); - usage_percentage = usage_percentage > 100 ? 100 : usage_percentage; // Cap at 100% - usageDisplay = ` -
-

${service.service['driver.interface']} (${service.service['driver.method']}):

- ${monthly_usage} used of ${monthly_limit} -
-
${usage_percentage}%
-
-
- `; - } - else { - usageDisplay = ` -
-

${service.service['driver.interface']} (${service.service['driver.method']}):

- ${i18n('usage')}: ${monthly_usage} (${i18n('unlimited')}) -
- `; - } - h += usageDisplay; - }); - - // Append driver usage bars to the container - $('.settings-content[data-settings="usage"]').append(`
${h}
`); - } - }) - - // df - $.ajax({ - url: api_origin + "/df", - type: 'GET', - async: true, - contentType: "application/json", - headers: { - "Authorization": "Bearer " + auth_token - }, - statusCode: { - 401: function () { - logout(); - }, - }, - success: function (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(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(byte_format(general_used)); - $('#storage-capacity').html(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', - }); - } - } - }) - $(el_window).find('.change-password').on('click', function (e) { UIWindowChangePassword({ window_options:{ From 0ed5b206273715ac5b0b8b5206f36827bcf498e2 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Mon, 15 Apr 2024 16:51:31 +0100 Subject: [PATCH 3/7] Settings: Move 'Account' tab into its own file --- src/UI/Settings/UITabAccount.js | 134 ++++++++++++++++++++++++++++ src/UI/Settings/UIWindowSettings.js | 108 +--------------------- 2 files changed, 136 insertions(+), 106 deletions(-) create mode 100644 src/UI/Settings/UITabAccount.js diff --git a/src/UI/Settings/UITabAccount.js b/src/UI/Settings/UITabAccount.js new file mode 100644 index 00000000..398ff4f3 --- /dev/null +++ b/src/UI/Settings/UITabAccount.js @@ -0,0 +1,134 @@ +/** + * Copyright (C) 2024 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'; + +// About +export default { + id: 'account', + title_i18n_key: 'account', + icon: 'user.svg', + html: () => { + let h = `

${i18n('account')}

`; + // change password button + h += `
`; + h += `${i18n('password')}`; + h += `
`; + h += ``; + h += `
`; + h += `
`; + + // change username button + h += `
`; + h += `
`; + h += `${i18n('username')}`; + h += `${user.username}`; + h += `
`; + h += `
`; + h += ``; + h += `
` + h += `
`; + + // change email button + if(user.email){ + h += `
`; + h += `
`; + h += `${i18n('email')}`; + h += `${user.email}`; + h += `
`; + h += `
`; + h += ``; + h += `
`; + h += `
`; + } + + // session manager + h += `
`; + h += `${i18n('sessions')}`; + 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) { + console.log('change email', $el_window.attr('data-element_uuid')); + 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, + } + }); + }); + }, +}; diff --git a/src/UI/Settings/UIWindowSettings.js b/src/UI/Settings/UIWindowSettings.js index 8758ccac..59300f4a 100644 --- a/src/UI/Settings/UIWindowSettings.js +++ b/src/UI/Settings/UIWindowSettings.js @@ -25,6 +25,7 @@ import changeLanguage from "../../i18n/i18nChangeLanguage.js" import UIWindowConfirmUserDeletion from './UIWindowConfirmUserDeletion.js'; import AboutTab from './UITabAbout.js'; import UsageTab from './UITabUsage.js'; +import AccountTab from './UITabAccount.js'; import UIWindowThemeDialog from '../UIWindowThemeDialog.js'; import UIWindowManageSessions from '../UIWindowManageSessions.js'; @@ -35,7 +36,7 @@ async function UIWindowSettings(options){ const tabs = [ AboutTab, UsageTab, - // AccountTab, + AccountTab, // PersonalizationTab, // LanguageTab, // ClockTab, @@ -50,7 +51,6 @@ async function UIWindowSettings(options){ tabs.forEach((tab, i) => { h += `
${i18n(tab.title_i18n_key)}
`; }); - h += `
${i18n('account')}
`; h += `
${i18n('personalization')}
`; h += `
${i18n('language')}
`; h += `
${i18n('clock')}
`; @@ -65,59 +65,6 @@ async function UIWindowSettings(options){
`; }); - // Account - h += `
`; - h += `

${i18n('account')}

`; - // change password button - h += `
`; - h += `${i18n('password')}`; - h += `
`; - h += ``; - h += `
`; - h += `
`; - - // change username button - h += `
`; - h += `
`; - h += `${i18n('username')}`; - h += `${user.username}`; - h += `
`; - h += `
`; - h += ``; - h += `
` - h += `
`; - - // change email button - if(user.email){ - h += `
`; - h += `
`; - h += `${i18n('email')}`; - h += `${user.email}`; - h += `
`; - h += `
`; - h += ``; - h += `
`; - h += `
`; - } - - // session manager - h += `
`; - h += `${i18n('sessions')}`; - h += `
`; - h += ``; - h += `
`; - h += `
`; - - // 'Delete Account' button - h += `
`; - h += `${i18n("delete_account")}`; - h += `
`; - h += ``; - h += `
`; - h += `
`; - - h += `
`; - // Personalization h += `
`; h += `

${i18n('personalization')}

`; @@ -200,47 +147,6 @@ async function UIWindowSettings(options){ const $el_window = $(el_window); tabs.forEach(tab => tab.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-email').on('click', function (e) { - console.log('change email', $(el_window).attr('data-element_uuid')); - UIWindowChangeEmail({ - 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-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-ui-colors').on('click', function (e) { UIWindowThemeDialog({ window_options:{ @@ -251,16 +157,6 @@ async function UIWindowSettings(options){ }); }) - $(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).on('click', '.settings-sidebar-item', function(){ const $this = $(this); const settings = $this.attr('data-settings'); From 6d1c807879be9c0995bcb59e1db61e272d677815 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Mon, 15 Apr 2024 16:50:29 +0100 Subject: [PATCH 4/7] Settings: Move 'Personalization' tab into its own file --- src/UI/Settings/UITabPersonalization.js | 47 +++++++++++++++++++++++++ src/UI/Settings/UIWindowSettings.js | 26 ++------------ 2 files changed, 49 insertions(+), 24 deletions(-) create mode 100644 src/UI/Settings/UITabPersonalization.js diff --git a/src/UI/Settings/UITabPersonalization.js b/src/UI/Settings/UITabPersonalization.js new file mode 100644 index 00000000..79977d3a --- /dev/null +++ b/src/UI/Settings/UITabPersonalization.js @@ -0,0 +1,47 @@ +/** + * Copyright (C) 2024 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'; + +// About +export default { + id: 'personalization', + title_i18n_key: 'personalization', + icon: 'palette-outline.svg', + html: () => { + return ` +

${i18n('personalization')}

+
+ ${i18n('ui_colors')} +
+ +
+
`; + }, + 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, + } + }); + }); + }, +}; diff --git a/src/UI/Settings/UIWindowSettings.js b/src/UI/Settings/UIWindowSettings.js index 59300f4a..6d59664f 100644 --- a/src/UI/Settings/UIWindowSettings.js +++ b/src/UI/Settings/UIWindowSettings.js @@ -26,6 +26,7 @@ import UIWindowConfirmUserDeletion from './UIWindowConfirmUserDeletion.js'; import AboutTab from './UITabAbout.js'; import UsageTab from './UITabUsage.js'; import AccountTab from './UITabAccount.js'; +import PersonalizationTab from './UITabPersonalization.js'; import UIWindowThemeDialog from '../UIWindowThemeDialog.js'; import UIWindowManageSessions from '../UIWindowManageSessions.js'; @@ -37,7 +38,7 @@ async function UIWindowSettings(options){ AboutTab, UsageTab, AccountTab, - // PersonalizationTab, + PersonalizationTab, // LanguageTab, // ClockTab, ]; @@ -51,7 +52,6 @@ async function UIWindowSettings(options){ tabs.forEach((tab, i) => { h += `
${i18n(tab.title_i18n_key)}
`; }); - h += `
${i18n('personalization')}
`; h += `
${i18n('language')}
`; h += `
${i18n('clock')}
`; h += `
`; @@ -65,18 +65,6 @@ async function UIWindowSettings(options){
`; }); - // Personalization - h += `
`; - h += `

${i18n('personalization')}

`; - // change password button - h += `
`; - h += `${i18n('ui_colors')}`; - h += `
`; - h += ``; - h += `
`; - h += `
`; - h += `
`; - // Language h += `
`; h += `

${i18n('language')}

`; @@ -147,16 +135,6 @@ async function UIWindowSettings(options){ const $el_window = $(el_window); tabs.forEach(tab => tab.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).on('click', '.settings-sidebar-item', function(){ const $this = $(this); const settings = $this.attr('data-settings'); From 17adef11a6476109967b59ec3bad67ff96ca5242 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Mon, 15 Apr 2024 17:24:16 +0100 Subject: [PATCH 5/7] Settings: Move 'Language' tab into its own file Also implement an optional `on_show` callback for settings tabs, to support the "select and clear the search field" behaviour we had before. --- src/UI/Settings/UITabLanguage.js | 83 +++++++++++++++++++++++++++++ src/UI/Settings/UIWindowSettings.js | 62 +++------------------ 2 files changed, 90 insertions(+), 55 deletions(-) create mode 100644 src/UI/Settings/UITabLanguage.js diff --git a/src/UI/Settings/UITabLanguage.js b/src/UI/Settings/UITabLanguage.js new file mode 100644 index 00000000..c0c36df2 --- /dev/null +++ b/src/UI/Settings/UITabLanguage.js @@ -0,0 +1,83 @@ +/** + * Copyright (C) 2024 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 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 = listSupportedLanguages(); + h += `
`; + for (let lang of available_languages) { + h += `
${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/UI/Settings/UIWindowSettings.js b/src/UI/Settings/UIWindowSettings.js index 6d59664f..20397f5d 100644 --- a/src/UI/Settings/UIWindowSettings.js +++ b/src/UI/Settings/UIWindowSettings.js @@ -27,6 +27,7 @@ import AboutTab from './UITabAbout.js'; import UsageTab from './UITabUsage.js'; import AccountTab from './UITabAccount.js'; import PersonalizationTab from './UITabPersonalization.js'; +import LanguageTab from './UITabLanguage.js'; import UIWindowThemeDialog from '../UIWindowThemeDialog.js'; import UIWindowManageSessions from '../UIWindowManageSessions.js'; @@ -39,7 +40,7 @@ async function UIWindowSettings(options){ UsageTab, AccountTab, PersonalizationTab, - // LanguageTab, + LanguageTab, // ClockTab, ]; @@ -52,7 +53,6 @@ async function UIWindowSettings(options){ tabs.forEach((tab, i) => { h += `
${i18n(tab.title_i18n_key)}
`; }); - h += `
${i18n('language')}
`; h += `
${i18n('clock')}
`; h += `
`; @@ -65,22 +65,6 @@ async function UIWindowSettings(options){
`; }); - // Language - h += `
`; - h += `

${i18n('language')}

`; - // search - h += `
`; - h += ``; - h += `
`; - // list of languages - const available_languages = listSupportedLanguages(); - h += `
`; - for (let lang of available_languages) { - h += `
${lang.name}
`; - } - h += `
`; - h += `
`; - // Clock h += `
`; h += `

${i18n('clock')}

`; @@ -146,46 +130,14 @@ async function UIWindowSettings(options){ // add active class to content $container.find('.settings-content').removeClass('active'); $content.addClass('active'); - // if language, focus on search - if(settings === 'language'){ - $content.find('.search').first().focus(); - // make sure all language items are visible - $content.find('.language-item').show(); - // empty search - $content.find('.search').val(''); + + // Run on_show handlers + const tab = tabs.find((tab) => tab.id === settings); + if (tab.on_show) { + tab.on_show($content); } }) - $(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', 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(); - } - }) - }); - $(el_window).on('change', 'select.change-clock-visible', function(e){ const $this = $(this); const value = $this.val(); From c6b0ed32bf5d2f2d384cb41517b31445d7b79db6 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Mon, 15 Apr 2024 17:07:37 +0100 Subject: [PATCH 6/7] Settings: Move 'Clock' tab into its own file --- src/UI/Settings/UITabClock.js | 45 +++++++++++++++++++++++++++++ src/UI/Settings/UIWindowSettings.js | 26 ++--------------- 2 files changed, 47 insertions(+), 24 deletions(-) create mode 100644 src/UI/Settings/UITabClock.js diff --git a/src/UI/Settings/UITabClock.js b/src/UI/Settings/UITabClock.js new file mode 100644 index 00000000..03eb7be9 --- /dev/null +++ b/src/UI/Settings/UITabClock.js @@ -0,0 +1,45 @@ +/** + * Copyright (C) 2024 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'; + +// About +export default { + id: 'clock', + title_i18n_key: 'clock', + icon: 'clock.svg', + html: () => { + return ` +

${i18n('clock')}

+
+ ${i18n('visibility')}: + +
`; + }, + init: ($el_window) => { + $el_window.on('change', 'select.change-clock-visible', function(e){ + window.change_clock_visible(this.value); + }); + + window.change_clock_visible(); + }, +}; diff --git a/src/UI/Settings/UIWindowSettings.js b/src/UI/Settings/UIWindowSettings.js index 20397f5d..a1827401 100644 --- a/src/UI/Settings/UIWindowSettings.js +++ b/src/UI/Settings/UIWindowSettings.js @@ -28,6 +28,7 @@ import UsageTab from './UITabUsage.js'; import AccountTab from './UITabAccount.js'; import PersonalizationTab from './UITabPersonalization.js'; import LanguageTab from './UITabLanguage.js'; +import ClockTab from './UITabClock.js'; import UIWindowThemeDialog from '../UIWindowThemeDialog.js'; import UIWindowManageSessions from '../UIWindowManageSessions.js'; @@ -41,7 +42,7 @@ async function UIWindowSettings(options){ AccountTab, PersonalizationTab, LanguageTab, - // ClockTab, + ClockTab, ]; let h = ''; @@ -53,7 +54,6 @@ async function UIWindowSettings(options){ tabs.forEach((tab, i) => { h += `
${i18n(tab.title_i18n_key)}
`; }); - h += `
${i18n('clock')}
`; h += `
`; // content @@ -65,19 +65,6 @@ async function UIWindowSettings(options){
`; }); - // Clock - h += `
`; - h += `

${i18n('clock')}

`; - h += `
` - h += `${i18n('visibility')}:` - h += `` - h += `
` - h += `
`; - h += `
`; h += ``; h += ``; @@ -138,15 +125,6 @@ async function UIWindowSettings(options){ } }) - $(el_window).on('change', 'select.change-clock-visible', function(e){ - const $this = $(this); - const value = $this.val(); - - window.change_clock_visible(value); - }) - - window.change_clock_visible(); - resolve(el_window); }); } From 868202ba413091f46cea60d1dd11c5b2361cf301 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Mon, 15 Apr 2024 17:33:54 +0100 Subject: [PATCH 7/7] Settings: Add desktop-background setting to 'Personalization' tab --- src/UI/Settings/UITabPersonalization.js | 16 ++++++++++++++++ src/UI/UIWindowDesktopBGSettings.js | 7 +++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/UI/Settings/UITabPersonalization.js b/src/UI/Settings/UITabPersonalization.js index 79977d3a..036ddd42 100644 --- a/src/UI/Settings/UITabPersonalization.js +++ b/src/UI/Settings/UITabPersonalization.js @@ -17,6 +17,7 @@ * along with this program. If not, see . */ import UIWindowThemeDialog from '../UIWindowThemeDialog.js'; +import UIWindowDesktopBGSettings from '../UIWindowDesktopBGSettings.js'; // About export default { @@ -31,6 +32,12 @@ export default {
+ +
+ ${i18n('background')} +
+ +
`; }, init: ($el_window) => { @@ -43,5 +50,14 @@ export default { } }); }); + $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, + } + }); + }); }, }; diff --git a/src/UI/UIWindowDesktopBGSettings.js b/src/UI/UIWindowDesktopBGSettings.js index 3b0c9838..e8a18b4c 100644 --- a/src/UI/UIWindowDesktopBGSettings.js +++ b/src/UI/UIWindowDesktopBGSettings.js @@ -19,7 +19,9 @@ import UIWindow from './UIWindow.js' -async function UIWindowDesktopBGSettings(){ +async function UIWindowDesktopBGSettings(options){ + options = options ?? {}; + return new Promise(async (resolve) => { let h = ''; const original_background_css = $('body').attr('style'); @@ -103,7 +105,8 @@ async function UIWindowDesktopBGSettings(){ height: '100%', 'background-color': 'rgb(245 247 249)', 'backdrop-filter': 'blur(3px)', - } + }, + ...options.window_options, }) if(window.desktop_bg_url !== undefined && window.desktop_bg_url !== null){