Commands: Spawn multiple commands asynchronously

This commit is contained in:
Romain Vigier
2026-08-08 22:09:40 +02:00
parent 867f99e340
commit 01f90bf029
15 changed files with 261 additions and 28 deletions
+1
View File
@@ -20,6 +20,7 @@
"@girs/gsk-4.0": "^4.1.0", "@girs/gsk-4.0": "^4.1.0",
"@girs/gtk-4.0": "^4.1.0", "@girs/gtk-4.0": "^4.1.0",
"@girs/meta-18": "^4.1.0", "@girs/meta-18": "^4.1.0",
"@girs/pango-1.0": "^4.1.0",
"@girs/shell-18": "^4.1.0", "@girs/shell-18": "^4.1.0",
"eslint-config-prettier": "^10.1.8", "eslint-config-prettier": "^10.1.8",
"eslint-plugin-jsdoc": "^63.2.0", "eslint-plugin-jsdoc": "^63.2.0",
+1
View File
@@ -24,6 +24,7 @@
"@girs/gsk-4.0": "^4.1.0", "@girs/gsk-4.0": "^4.1.0",
"@girs/gtk-4.0": "^4.1.0", "@girs/gtk-4.0": "^4.1.0",
"@girs/meta-18": "^4.1.0", "@girs/meta-18": "^4.1.0",
"@girs/pango-1.0": "^4.1.0",
"@girs/shell-18": "^4.1.0", "@girs/shell-18": "^4.1.0",
"eslint-config-prettier": "^10.1.8", "eslint-config-prettier": "^10.1.8",
"eslint-plugin-jsdoc": "^63.2.0", "eslint-plugin-jsdoc": "^63.2.0",
+26
View File
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
SPDX-FileCopyrightText: Jakub Steiner
SPDX-License-Identifier: CC0-1.0
-->
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:ns0="http://www.w3.org/2000/svg" xmlns:ns1="https://www.gtk.org/grappa" xmlns:ns3="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" ns1:rendering="symbolic" ns1:version="1" ns1:state-names="outline empty" ns1:state="outline" viewBox="0 0 16 16" preserveAspectRatio="xMidYMid meet" gpa:state="outline" ns0:state="outline" xmlns="http://www.w3.org/2000/svg">
<title>plus</title>
<path id="plus" fill="none" stroke="rgb(0,0,0)" stroke-width="1.100" stroke-linecap="round" stroke-linejoin="round" d="M 2 8 L 14 8 M 8 2 L 8 14" ns1:stroke-minwidth="25%" ns1:stroke-maxwidth="150%" class="transparent-fill foreground-stroke foreground-stroke" ns1:states="outline" data-stroke-mid="2.0" data-stroke-min="0.5" data-stroke-max="3.0"></path>
<metadata>
<rdf:rdf>
<work>
<license rdf:resource="https://creativecommons.org/publicdomain/zero/1.0/"/>
<dc:creator>
<agent>
<dc:title>Jakub Steiner</dc:title>
</agent>
</dc:creator>
<dc:subject>
<rdf:bag>
<rdf:li>list-add add plus create</rdf:li>
</rdf:bag>
</dc:subject>
</work>
</rdf:rdf>
</metadata>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

+29
View File
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
SPDX-FileCopyrightText: Jakub Steiner
SPDX-License-Identifier: CC0-1.0
-->
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:ns0="http://www.w3.org/2000/svg" xmlns:ns1="https://www.gtk.org/grappa" xmlns:ns3="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" ns1:rendering="symbolic" ns1:version="1" ns1:state="outline" ns1:state-names="outline empty" viewBox="0 0 16 16" preserveAspectRatio="xMidYMid meet" gpa:state="outline" ns0:state="outline" xmlns="http://www.w3.org/2000/svg">
<title>user-trash</title>
<path d="M 3 4 L 3 13 C 3 14.1045694, 3.89543056 15, 5 15 L 11 15 C 12.1045694 15, 13 14.1045694, 13 13 L 13 4" id="path0" stroke-width="1.100" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(0,0,0)" fill="none" class="foreground-stroke transparent-fill foreground-stroke" ns1:states="outline" ns1:stroke-minwidth="25%" ns1:stroke-maxwidth="150%" data-stroke-mid="2.0" data-stroke-min="0.5" data-stroke-max="3.0"></path>
<path d="M 15 4 L 1 4" id="path1" stroke-width="1.100" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(0,0,0)" fill="none" class="foreground-stroke transparent-fill foreground-stroke" ns1:states="outline" ns1:stroke-minwidth="25%" ns1:stroke-maxwidth="150%" data-stroke-mid="2.0" data-stroke-min="0.5" data-stroke-max="3.0"></path>
<path d="M 5 4 L 5 3 C 5 1.89543045, 5.89543056 1, 7 1 L 9 1 C 10.1045694 1, 11 1.89543045, 11 3 L 11 4" id="path2" stroke-width="1.100" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(0,0,0)" fill="none" class="foreground-stroke transparent-fill foreground-stroke" ns1:states="outline" ns1:stroke-minwidth="25%" ns1:stroke-maxwidth="150%" data-stroke-mid="2.0" data-stroke-min="0.5" data-stroke-max="3.0"></path>
<path d="M 6.5 7 L 6.5 12 M 9.49961376 7 L 9.49961376 12" id="path3" stroke-width="0.550" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(0,0,0)" fill="none" class="foreground-stroke transparent-fill foreground-stroke" ns1:states="outline" ns1:stroke-minwidth="25%" ns1:stroke-maxwidth="200%" data-stroke-mid="1.0" data-stroke-min="0.25" data-stroke-max="2.0"></path>
<metadata>
<rdf:rdf>
<work>
<license rdf:resource="https://creativecommons.org/publicdomain/zero/1.0/"/>
<dc:subject>
<rdf:bag>
<rdf:li>trash bin deleted wastebasket user folder</rdf:li>
</rdf:bag>
</dc:subject>
<dc:creator>
<agent>
<dc:title>Jakub Steiner</dc:title>
</agent>
</dc:creator>
</work>
</rdf:rdf>
</metadata>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

@@ -28,9 +28,15 @@ SPDX-License-Identifier: GPL-3.0-or-later
<key name="sunrise" type="s"> <key name="sunrise" type="s">
<default>""</default> <default>""</default>
</key> </key>
<key name="sunrise-commands" type="as">
<default>[]</default>
</key>
<key name="sunset" type="s"> <key name="sunset" type="s">
<default>""</default> <default>""</default>
</key> </key>
<key name="sunset-commands" type="as">
<default>[]</default>
</key>
</schema> </schema>
<schema id="org.gnome.shell.extensions.nightthemeswitcher.time" path="/org/gnome/shell/extensions/nightthemeswitcher/time/"> <schema id="org.gnome.shell.extensions.nightthemeswitcher.time" path="/org/gnome/shell/extensions/nightthemeswitcher/time/">
<key name="nightthemeswitcher-ondemand-keybinding" type="as"> <key name="nightthemeswitcher-ondemand-keybinding" type="as">
+3
View File
@@ -7,8 +7,10 @@ SPDX-License-Identifier: GPL-3.0-or-later
<gresource prefix="/org/gnome/Shell/Extensions/nightthemeswitcher/preferences"> <gresource prefix="/org/gnome/Shell/Extensions/nightthemeswitcher/preferences">
<file compressed="true" preprocess="xml-stripblanks">assets/preview-window-dark.svg</file> <file compressed="true" preprocess="xml-stripblanks">assets/preview-window-dark.svg</file>
<file compressed="true" preprocess="xml-stripblanks">assets/preview-window-light.svg</file> <file compressed="true" preprocess="xml-stripblanks">assets/preview-window-light.svg</file>
<file compressed="true" preprocess="xml-stripblanks" alias="icons/scalable/actions/nightthemeswitcher-add-symbolic.svg">icons/add-symbolic.svg</file>
<file compressed="true" preprocess="xml-stripblanks" alias="icons/scalable/actions/nightthemeswitcher-code-symbolic.svg">icons/code-symbolic.svg</file> <file compressed="true" preprocess="xml-stripblanks" alias="icons/scalable/actions/nightthemeswitcher-code-symbolic.svg">icons/code-symbolic.svg</file>
<file compressed="true" preprocess="xml-stripblanks" alias="icons/scalable/actions/nightthemeswitcher-translate-symbolic.svg">icons/translate-symbolic.svg</file> <file compressed="true" preprocess="xml-stripblanks" alias="icons/scalable/actions/nightthemeswitcher-translate-symbolic.svg">icons/translate-symbolic.svg</file>
<file compressed="true" preprocess="xml-stripblanks" alias="icons/scalable/actions/nightthemeswitcher-trash-symbolic.svg">icons/trash-symbolic.svg</file>
<file compressed="true" preprocess="xml-stripblanks" alias="icons/scalable/apps/nightthemeswitcher-symbolic.svg">icons/nightthemeswitcher-symbolic.svg</file> <file compressed="true" preprocess="xml-stripblanks" alias="icons/scalable/apps/nightthemeswitcher-symbolic.svg">icons/nightthemeswitcher-symbolic.svg</file>
<file compressed="true" preprocess="xml-stripblanks" alias="icons/scalable/categories/nightthemeswitcher-appearance-symbolic.svg">icons/appearance-symbolic.svg</file> <file compressed="true" preprocess="xml-stripblanks" alias="icons/scalable/categories/nightthemeswitcher-appearance-symbolic.svg">icons/appearance-symbolic.svg</file>
<file compressed="true" preprocess="xml-stripblanks" alias="icons/scalable/categories/nightthemeswitcher-commands-symbolic.svg">icons/commands-symbolic.svg</file> <file compressed="true" preprocess="xml-stripblanks" alias="icons/scalable/categories/nightthemeswitcher-commands-symbolic.svg">icons/commands-symbolic.svg</file>
@@ -19,6 +21,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
<file compressed="true" preprocess="xml-stripblanks">ui/AppearanceChooser.ui</file> <file compressed="true" preprocess="xml-stripblanks">ui/AppearanceChooser.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/AppearancePage.ui</file> <file compressed="true" preprocess="xml-stripblanks">ui/AppearancePage.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/BackgroundButton.ui</file> <file compressed="true" preprocess="xml-stripblanks">ui/BackgroundButton.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/CommandsEditor.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/CommandsPage.ui</file> <file compressed="true" preprocess="xml-stripblanks">ui/CommandsPage.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/ContributePage.ui</file> <file compressed="true" preprocess="xml-stripblanks">ui/ContributePage.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/ShortcutButton.ui</file> <file compressed="true" preprocess="xml-stripblanks">ui/ShortcutButton.ui</file>
+23
View File
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
SPDX-FileCopyrightText: Night Theme Switcher Contributors
SPDX-License-Identifier: GPL-3.0-or-later
-->
<interface domain="nightthemeswitcher@romainvigier.fr">
<template class="CommandsEditor" parent="AdwPreferencesGroup">
<child type="header-suffix">
<object class="GtkButton">
<style>
<class name="flat"/>
</style>
<signal name="clicked" handler="onAddButtonClicked"/>
<property name="child">
<object class="AdwButtonContent">
<property name="icon-name">nightthemeswitcher-add-symbolic</property>
<property name="label" translatable="yes">Add command</property>
</object>
</property>
</object>
</child>
</template>
</interface>
+12 -17
View File
@@ -10,27 +10,22 @@ SPDX-License-Identifier: GPL-3.0-or-later
<property name="icon-name">nightthemeswitcher-commands-symbolic</property> <property name="icon-name">nightthemeswitcher-commands-symbolic</property>
<child> <child>
<object class="AdwPreferencesGroup"> <object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Run commands</property>
<property name="header-suffix">
<object class="GtkSwitch" id="enabled_switch">
<property name="valign">center</property>
</object>
</property>
<child> <child>
<object class="AdwEntryRow" id="sunrise_entry"> <object class="AdwSwitchRow" id="enabled_switch">
<property name="title" translatable="yes">Sunrise</property> <property name="title" translatable="yes">Run commands</property>
<property name="input-purpose">terminal</property>
<property name="attributes">0 -1 font-desc "Mono"</property>
</object>
</child>
<child>
<object class="AdwEntryRow" id="sunset_entry">
<property name="title" translatable="yes">Sunset</property>
<property name="input-purpose">terminal</property>
<property name="attributes">0 -1 font-desc "Mono"</property>
</object> </object>
</child> </child>
</object> </object>
</child> </child>
<child>
<object class="CommandsEditor" id="sunrise_commands_editor">
<property name="title" translatable="yes">Sunrise commands</property>
</object>
</child>
<child>
<object class="CommandsEditor" id="sunset_commands_editor">
<property name="title" translatable="yes">Sunset commands</property>
</object>
</child>
</template> </template>
</interface> </interface>
+1
View File
@@ -40,6 +40,7 @@ preferences = [
'preferences/AppearancePreview.js', 'preferences/AppearancePreview.js',
'preferences/BackgroundButton.js', 'preferences/BackgroundButton.js',
'preferences/ColorChooser.js', 'preferences/ColorChooser.js',
'preferences/CommandsEditor.js',
'preferences/CommandsPage.js', 'preferences/CommandsPage.js',
'preferences/ContributePage.js', 'preferences/ContributePage.js',
'preferences/ShortcutButton.js', 'preferences/ShortcutButton.js',
+1 -1
View File
@@ -6,7 +6,7 @@
"settings-schema": "@DNS@", "settings-schema": "@DNS@",
"url": "https://nightthemeswitcher.romainvigier.fr", "url": "https://nightthemeswitcher.romainvigier.fr",
"session-modes": ["unlock-dialog", "user"], "session-modes": ["unlock-dialog", "user"],
"shell-version": ["50"], "shell-version": ["51"],
"version": @VERSION@, "version": @VERSION@,
"build-type": "@BUILD_TYPE@" "build-type": "@BUILD_TYPE@"
} }
+22
View File
@@ -9,6 +9,7 @@ import Gio from "gi://Gio";
*/ */
export function migrate(extension) { export function migrate(extension) {
initializeAccentColorSettings(extension); initializeAccentColorSettings(extension);
migrateCommandsSettings(extension);
} }
/** /**
@@ -25,3 +26,24 @@ function initializeAccentColorSettings(extension) {
if (accentColorSettings.get_string("night") === "unset") if (accentColorSettings.get_string("night") === "unset")
accentColorSettings.set_string("night", interfaceSettings.get_string("accent-color")); accentColorSettings.set_string("night", interfaceSettings.get_string("accent-color"));
} }
/**
* Move the commands from single strings to arrays of strings.
* @param {ExtensionBase} extension The extension base class.
*/
function migrateCommandsSettings(extension) {
const commandsSettings = extension.getSettings(`${extension.metadata["settings-schema"]}.commands`);
const oldSunriseCommand = commandsSettings.get_string("sunrise");
const oldSunsetCommand = commandsSettings.get_string("sunset");
if (oldSunriseCommand) {
commandsSettings.set_strv("sunrise-commands", [oldSunriseCommand]);
commandsSettings.set_string("sunrise", "");
}
if (oldSunsetCommand) {
commandsSettings.set_strv("sunset-commands", [oldSunsetCommand]);
commandsSettings.set_string("sunset", "");
}
}
+6 -4
View File
@@ -33,9 +33,11 @@ export class CommandsSwitcher extends Switcher {
#onTimeChanged(time) { #onTimeChanged(time) {
if (time === Time.UNKNOWN) return; if (time === Time.UNKNOWN) return;
const command = this.#settings.get_string(time === Time.DAY ? "sunrise" : "sunset"); const commands = this.#settings.get_strv(time === Time.DAY ? "sunrise-commands" : "sunset-commands");
if (!command) return; if (commands.length === 0) return;
GLib.spawn_async(null, ["sh", "-c", command], null, GLib.SpawnFlags.SEARCH_PATH, null); commands.forEach((command) => {
debug.message(`Spawned ${time} command.`); GLib.spawn_async(null, ["sh", "-c", command], null, GLib.SpawnFlags.SEARCH_PATH, null);
});
debug.message(`Spawned ${time} commands.`);
} }
} }
+108
View File
@@ -0,0 +1,108 @@
// SPDX-FileCopyrightText: Night Theme Switcher Contributors
// SPDX-License-Identifier: GPL-3.0-or-later
import Adw from "gi://Adw";
import GObject from "gi://GObject";
import Gtk from "gi://Gtk";
import Pango from "gi://Pango";
import { gettext as _ } from "resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js";
export class CommandsEditor extends Adw.PreferencesGroup {
#commands = new Gtk.StringList();
static {
GObject.registerClass(
{
GTypeName: "CommandsEditor",
Template: "resource:///org/gnome/Shell/Extensions/nightthemeswitcher/preferences/ui/CommandsEditor.ui",
Properties: {
commands: GObject.ParamSpec.jsobject(
"commands",
"Commands",
"Array of commands",
GObject.ParamFlags.READWRITE,
),
},
},
this,
);
}
constructor({ ...params } = {}) {
super(params);
this.bind_model(this.#commands, (item) => this.#createCommandEntryRow(item));
}
get commands() {
const commands = [];
for (let i = 0; i < this.#commands.get_n_items(); i++) {
const command = this.#commands.get_string(i);
if (command) commands.push(command);
}
return commands;
}
set commands(commands) {
this.#commands.splice(0, this.#commands.get_n_items(), commands);
this.notify("commands");
}
/**
* Create an entry row from the given string object.
* @param {Gtk.StringObject} strObject The string object.
* @returns {Adw.EntryRow} The created entry row.
*/
#createCommandEntryRow(strObject) {
const findItemPositionInCommands = () => {
let position = -1;
for (let i = 0; i < this.#commands.get_n_items(); i++) {
const listItem = this.#commands.get_item(i);
if (listItem === strObject) {
position = i;
break;
}
}
return position;
};
const attrList = Pango.AttrList.new();
attrList.insert(Pango.attr_family_new("monospace"));
const entryRow = new Adw.EntryRow({
title: _("Command"),
text: strObject.string,
showApplyButton: true,
inputHints: Gtk.InputHints.NO_SPELLCHECK,
inputPurpose: Gtk.InputPurpose.TERMINAL,
attributes: attrList,
});
entryRow.connect("apply", () => {
const position = findItemPositionInCommands(strObject);
if (position === -1) return;
this.#commands.splice(position, 1, [entryRow.text]);
this.notify("commands");
});
const removeButton = new Gtk.Button({
tooltipText: _("Remove command"),
iconName: "nightthemeswitcher-trash-symbolic",
valign: Gtk.Align.CENTER,
cssClasses: ["circular", "flat"],
});
removeButton.connect("clicked", () => {
const position = findItemPositionInCommands(strObject);
if (position === -1) return;
this.#commands.remove(position);
this.notify("commands");
});
entryRow.add_suffix(removeButton);
return entryRow;
}
onAddButtonClicked() {
this.#commands.append("");
}
}
+19 -5
View File
@@ -11,17 +11,31 @@ export class CommandsPage extends Adw.PreferencesPage {
{ {
GTypeName: "CommandsPage", GTypeName: "CommandsPage",
Template: "resource:///org/gnome/Shell/Extensions/nightthemeswitcher/preferences/ui/CommandsPage.ui", Template: "resource:///org/gnome/Shell/Extensions/nightthemeswitcher/preferences/ui/CommandsPage.ui",
InternalChildren: ["enabled_switch", "sunrise_entry", "sunset_entry"], InternalChildren: ["enabled_switch", "sunrise_commands_editor", "sunset_commands_editor"],
}, },
this, this,
); );
} }
constructor({ settings, ...params } = {}) { constructor({ commandsSettings, ...params } = {}) {
super(params); super(params);
settings.bind("enabled", this._enabled_switch, "active", Gio.SettingsBindFlags.DEFAULT); commandsSettings.bind("enabled", this._enabled_switch, "active", Gio.SettingsBindFlags.DEFAULT);
settings.bind("sunrise", this._sunrise_entry, "text", Gio.SettingsBindFlags.DEFAULT);
settings.bind("sunset", this._sunset_entry, "text", Gio.SettingsBindFlags.DEFAULT); this._sunrise_commands_editor.commands = commandsSettings.get_strv("sunrise-commands");
commandsSettings.connect("changed::sunrise-commands", () => {
this._sunrise_commands_editor.commands = commandsSettings.get_strv("sunrise-commands");
});
this._sunrise_commands_editor.connect("notify::commands", () => {
commandsSettings.set_strv("sunrise-commands", this._sunrise_commands_editor.commands);
});
this._sunset_commands_editor.commands = commandsSettings.get_strv("sunset-commands");
commandsSettings.connect("changed::sunset-commands", () => {
this._sunset_commands_editor.commands = commandsSettings.get_strv("sunset-commands");
});
this._sunset_commands_editor.connect("notify::commands", () => {
commandsSettings.set_strv("sunset-commands", this._sunset_commands_editor.commands);
});
} }
} }
+3 -1
View File
@@ -48,6 +48,7 @@ export default class NightThemeSwitcherPreferences extends ExtensionPreferences
const { AppearancePreview } = await import("./preferences/AppearancePreview.js"); const { AppearancePreview } = await import("./preferences/AppearancePreview.js");
const { BackgroundButton } = await import("./preferences/BackgroundButton.js"); const { BackgroundButton } = await import("./preferences/BackgroundButton.js");
const { ColorChooser } = await import("./preferences/ColorChooser.js"); const { ColorChooser } = await import("./preferences/ColorChooser.js");
const { CommandsEditor } = await import("./preferences/CommandsEditor.js");
const { CommandsPage } = await import("./preferences/CommandsPage.js"); const { CommandsPage } = await import("./preferences/CommandsPage.js");
const { ContributePage } = await import("./preferences/ContributePage.js"); const { ContributePage } = await import("./preferences/ContributePage.js");
const { ShortcutButton } = await import("./preferences/ShortcutButton.js"); const { ShortcutButton } = await import("./preferences/ShortcutButton.js");
@@ -60,6 +61,7 @@ export default class NightThemeSwitcherPreferences extends ExtensionPreferences
GObject.type_ensure(AppearancePreview); GObject.type_ensure(AppearancePreview);
GObject.type_ensure(BackgroundButton); GObject.type_ensure(BackgroundButton);
GObject.type_ensure(ColorChooser); GObject.type_ensure(ColorChooser);
GObject.type_ensure(CommandsEditor);
GObject.type_ensure(CommandsPage); GObject.type_ensure(CommandsPage);
GObject.type_ensure(ContributePage); GObject.type_ensure(ContributePage);
GObject.type_ensure(ShortcutButton); GObject.type_ensure(ShortcutButton);
@@ -71,7 +73,7 @@ export default class NightThemeSwitcherPreferences extends ExtensionPreferences
new AppearancePage({ new AppearancePage({
accentColorSettings: this.getSettings(`${this.metadata["settings-schema"]}.accent-color`), accentColorSettings: this.getSettings(`${this.metadata["settings-schema"]}.accent-color`),
}), }),
new CommandsPage({ settings: this.getSettings(`${this.metadata["settings-schema"]}.commands`) }), new CommandsPage({ commandsSettings: this.getSettings(`${this.metadata["settings-schema"]}.commands`) }),
new TweaksPage({ new TweaksPage({
locationSettings: this.getSettings(`${this.metadata["settings-schema"]}.location`), locationSettings: this.getSettings(`${this.metadata["settings-schema"]}.location`),
timeSettings: this.getSettings(`${this.metadata["settings-schema"]}.time`), timeSettings: this.getSettings(`${this.metadata["settings-schema"]}.time`),