Skip to content
Open
Show file tree
Hide file tree
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
108 changes: 108 additions & 0 deletions src/gui/src/UI/Settings/UITabKeyboardShortcuts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/**
* Keyboard Shortcuts Tab
*/

export default {
id: "keyboard-shortcuts",
title_i18n_key: "keyboard_shortcuts",
icon: "keyboard.svg",

html() {
const sections = [
{
title: "General",
list: [
{ keys: ["Ctrl / ⌘", "F"], text: "Search" },
{ keys: ["Ctrl / ⌘", "Z"], text: "Undo last action" },
{ keys: ["Esc"], text: "Close menus or dialogs" },
{ keys: ["F1"], text: "Open Keyboard Shortcuts" }
]
},
{
title: "Navigation",
list: [
{ keys: ["↑", "↓", "←", "→"], text: "Navigate items" },
{ keys: ["Enter"], text: "Open selected item" },
{ keys: ["Tab"], text: "Move to next focusable element" }
]
},
{
title: "File Management",
list: [
{ keys: ["Ctrl / ⌘", "C"], text: "Copy selected items" },
{ keys: ["Ctrl / ⌘", "V"], text: "Paste items" },
{ keys: ["Ctrl / ⌘", "X"], text: "Cut selected items" },
{ keys: ["Delete"], text: "Move to Trash" },
{ keys: ["Shift", "Delete"], text: "Delete permanently" }
]
},
{
title: "Windows",
list: [
{ keys: ["Alt", "F4"], text: "Close current window" }
]
}
];

const renderKeys = (keys) =>
keys
.map(k => `<kbd class="ks-key">${k}</kbd>`)
.join(`<span class="ks-plus">+</span>`);

let html = `
<div class="ks-wrapper">
<h2>Keyboard Shortcuts</h2>
<p class="ks-subtext">
Here are the shortcuts available in Puter.
macOS users can use ⌘ instead of Ctrl.
</p>
`;

sections.forEach(section => {
html += `
<div class="ks-section">
<h3>${section.title}</h3>
`;

section.list.forEach(item => {
html += `
<div class="ks-row">
<span class="ks-text">${item.text}</span>
<span class="ks-keys">${renderKeys(item.keys)}</span>
</div>
`;
});

html += `</div>`;
});

html += `
</div>

<style>
.ks-wrapper { padding: 20px; }
.ks-subtext { color: #666; margin-bottom: 20px; }
.ks-section { margin-bottom: 24px; }
.ks-row {
display: flex;
justify-content: space-between;
padding: 6px 0;
border-bottom: 1px solid #eee;
}
.ks-key {
display: inline-block;
padding: 4px 8px;
background: #f2f2f2;
border: 1px solid #ccc;
border-radius: 4px;
margin-right: 4px;
font-family: monospace;
font-size: 12px;
}
.ks-plus { margin: 0 4px; color: #999; }
</style>
`;

return html;
}
};
80 changes: 41 additions & 39 deletions src/gui/src/services/SettingsService.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,47 +16,49 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Service } from '../definitions.js';
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 UIElement from '../UI/UIElement.js';
const TSettingsTab = use('ui.traits.TSettingsTab');
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 KeyboardShortcutsTab from "../UI/Settings/UITabKeyboardShortcuts.js";
import PersonalizationTab from "../UI/Settings/UITabPersonalization.js";
import LanguageTag from "../UI/Settings/UITabLanguage.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,
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);
#tabs = [];
async _init() {
[
UsageTab,
AccountTab,
SecurityTab,
PersonalizationTab,
LanguageTag,
AboutTab,
KeyboardShortcutsTab,
].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);
}
}