formalconf 2.0.7 → 2.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/formalconf.js +246 -50
- package/package.json +1 -1
package/dist/formalconf.js
CHANGED
|
@@ -317,6 +317,7 @@ var CONFIGS_DIR = join(CONFIG_DIR, "configs");
|
|
|
317
317
|
var THEMES_DIR = join(CONFIG_DIR, "themes");
|
|
318
318
|
var PKG_CONFIG_PATH = join(CONFIG_DIR, "pkg-config.json");
|
|
319
319
|
var PKG_LOCK_PATH = join(CONFIG_DIR, "pkg-lock.json");
|
|
320
|
+
var THEME_CONFIG_PATH = join(CONFIG_DIR, "theme-config.json");
|
|
320
321
|
async function ensureDir2(path) {
|
|
321
322
|
await ensureDir(path);
|
|
322
323
|
}
|
|
@@ -446,7 +447,7 @@ function StatusIndicator({
|
|
|
446
447
|
// package.json
|
|
447
448
|
var package_default = {
|
|
448
449
|
name: "formalconf",
|
|
449
|
-
version: "2.0.
|
|
450
|
+
version: "2.0.8",
|
|
450
451
|
description: "Dotfiles management TUI for macOS - config management, package sync, and theme switching",
|
|
451
452
|
type: "module",
|
|
452
453
|
main: "./dist/formalconf.js",
|
|
@@ -4502,16 +4503,18 @@ function PackageMenu({ onBack }) {
|
|
|
4502
4503
|
// src/components/menus/ThemeMenu.tsx
|
|
4503
4504
|
import { useState as useState10, useEffect as useEffect6, useMemo as useMemo4 } from "react";
|
|
4504
4505
|
import { Box as Box16, Text as Text15 } from "ink";
|
|
4505
|
-
import { existsSync as
|
|
4506
|
+
import { existsSync as existsSync8, readdirSync as readdirSync5 } from "fs";
|
|
4506
4507
|
import { join as join6 } from "path";
|
|
4507
4508
|
|
|
4508
4509
|
// src/components/ThemeCard.tsx
|
|
4509
4510
|
import { Box as Box15, Text as Text14 } from "ink";
|
|
4510
4511
|
import { jsxDEV as jsxDEV18 } from "react/jsx-dev-runtime";
|
|
4511
|
-
function ThemeCard({ theme, isSelected, width }) {
|
|
4512
|
+
function ThemeCard({ theme, isSelected, width, isDeviceTheme }) {
|
|
4512
4513
|
const borderColor = isSelected ? colors.accent : colors.border;
|
|
4513
4514
|
const nameColor = isSelected ? colors.primary : colors.text;
|
|
4514
4515
|
const indicators = [];
|
|
4516
|
+
if (isDeviceTheme)
|
|
4517
|
+
indicators.push("device");
|
|
4515
4518
|
if (theme.hasBackgrounds)
|
|
4516
4519
|
indicators.push("bg");
|
|
4517
4520
|
if (theme.isLightMode)
|
|
@@ -4553,6 +4556,7 @@ function useThemeGrid({
|
|
|
4553
4556
|
layoutOverhead = 20,
|
|
4554
4557
|
minCardWidth = 28,
|
|
4555
4558
|
onSelect,
|
|
4559
|
+
onSelectAndSave,
|
|
4556
4560
|
onBack,
|
|
4557
4561
|
enabled = true
|
|
4558
4562
|
}) {
|
|
@@ -4602,8 +4606,12 @@ function useThemeGrid({
|
|
|
4602
4606
|
setSelectedIndex(prevIndex);
|
|
4603
4607
|
}
|
|
4604
4608
|
}
|
|
4605
|
-
if (key.return
|
|
4606
|
-
|
|
4609
|
+
if (key.return) {
|
|
4610
|
+
if (key.shift && onSelectAndSave) {
|
|
4611
|
+
onSelectAndSave(selectedIndex);
|
|
4612
|
+
} else if (onSelect) {
|
|
4613
|
+
onSelect(selectedIndex);
|
|
4614
|
+
}
|
|
4607
4615
|
}
|
|
4608
4616
|
});
|
|
4609
4617
|
const visibleStartIndex = scrollOffset * cardsPerRow;
|
|
@@ -4700,8 +4708,86 @@ async function parseTheme(themePath, themeName) {
|
|
|
4700
4708
|
|
|
4701
4709
|
// src/cli/set-theme.ts
|
|
4702
4710
|
import { parseArgs as parseArgs4 } from "util";
|
|
4703
|
-
import { readdirSync as readdirSync4, existsSync as
|
|
4711
|
+
import { readdirSync as readdirSync4, existsSync as existsSync7, rmSync, symlinkSync, unlinkSync } from "fs";
|
|
4704
4712
|
import { join as join5 } from "path";
|
|
4713
|
+
|
|
4714
|
+
// src/lib/theme-config.ts
|
|
4715
|
+
import { hostname } from "os";
|
|
4716
|
+
import { existsSync as existsSync6, readFileSync, writeFileSync } from "fs";
|
|
4717
|
+
var DEFAULT_CONFIG = {
|
|
4718
|
+
version: 1,
|
|
4719
|
+
defaultTheme: null,
|
|
4720
|
+
devices: {}
|
|
4721
|
+
};
|
|
4722
|
+
function getDeviceHostname() {
|
|
4723
|
+
return hostname();
|
|
4724
|
+
}
|
|
4725
|
+
function loadThemeConfig() {
|
|
4726
|
+
if (!existsSync6(THEME_CONFIG_PATH)) {
|
|
4727
|
+
return { ...DEFAULT_CONFIG, devices: {} };
|
|
4728
|
+
}
|
|
4729
|
+
try {
|
|
4730
|
+
const content = readFileSync(THEME_CONFIG_PATH, "utf-8");
|
|
4731
|
+
const parsed = JSON.parse(content);
|
|
4732
|
+
return {
|
|
4733
|
+
version: parsed.version ?? 1,
|
|
4734
|
+
defaultTheme: parsed.defaultTheme ?? null,
|
|
4735
|
+
devices: parsed.devices ?? {}
|
|
4736
|
+
};
|
|
4737
|
+
} catch {
|
|
4738
|
+
return { ...DEFAULT_CONFIG, devices: {} };
|
|
4739
|
+
}
|
|
4740
|
+
}
|
|
4741
|
+
async function saveThemeConfig(config) {
|
|
4742
|
+
await ensureConfigDir();
|
|
4743
|
+
writeFileSync(THEME_CONFIG_PATH, JSON.stringify(config, null, 2) + `
|
|
4744
|
+
`);
|
|
4745
|
+
}
|
|
4746
|
+
function getDeviceTheme() {
|
|
4747
|
+
const config = loadThemeConfig();
|
|
4748
|
+
const device = getDeviceHostname();
|
|
4749
|
+
const mapping = config.devices[device];
|
|
4750
|
+
if (mapping) {
|
|
4751
|
+
return mapping.theme;
|
|
4752
|
+
}
|
|
4753
|
+
return config.defaultTheme;
|
|
4754
|
+
}
|
|
4755
|
+
async function setDeviceTheme(themeName) {
|
|
4756
|
+
const config = loadThemeConfig();
|
|
4757
|
+
const device = getDeviceHostname();
|
|
4758
|
+
config.devices[device] = {
|
|
4759
|
+
theme: themeName,
|
|
4760
|
+
setAt: new Date().toISOString()
|
|
4761
|
+
};
|
|
4762
|
+
await saveThemeConfig(config);
|
|
4763
|
+
}
|
|
4764
|
+
async function setDefaultTheme(themeName) {
|
|
4765
|
+
const config = loadThemeConfig();
|
|
4766
|
+
config.defaultTheme = themeName;
|
|
4767
|
+
await saveThemeConfig(config);
|
|
4768
|
+
}
|
|
4769
|
+
async function clearDeviceTheme() {
|
|
4770
|
+
const config = loadThemeConfig();
|
|
4771
|
+
const device = getDeviceHostname();
|
|
4772
|
+
delete config.devices[device];
|
|
4773
|
+
await saveThemeConfig(config);
|
|
4774
|
+
}
|
|
4775
|
+
function listDeviceMappings() {
|
|
4776
|
+
const config = loadThemeConfig();
|
|
4777
|
+
const currentDevice = getDeviceHostname();
|
|
4778
|
+
return Object.entries(config.devices).map(([device, mapping]) => ({
|
|
4779
|
+
device,
|
|
4780
|
+
theme: mapping.theme,
|
|
4781
|
+
setAt: mapping.setAt,
|
|
4782
|
+
isCurrent: device === currentDevice
|
|
4783
|
+
}));
|
|
4784
|
+
}
|
|
4785
|
+
function getDefaultTheme() {
|
|
4786
|
+
const config = loadThemeConfig();
|
|
4787
|
+
return config.defaultTheme;
|
|
4788
|
+
}
|
|
4789
|
+
|
|
4790
|
+
// src/cli/set-theme.ts
|
|
4705
4791
|
var colors5 = {
|
|
4706
4792
|
red: "\x1B[0;31m",
|
|
4707
4793
|
green: "\x1B[0;32m",
|
|
@@ -4713,7 +4799,7 @@ var colors5 = {
|
|
|
4713
4799
|
};
|
|
4714
4800
|
async function listThemes() {
|
|
4715
4801
|
await ensureConfigDir();
|
|
4716
|
-
if (!
|
|
4802
|
+
if (!existsSync7(THEMES_DIR)) {
|
|
4717
4803
|
return [];
|
|
4718
4804
|
}
|
|
4719
4805
|
const entries = readdirSync4(THEMES_DIR, { withFileTypes: true });
|
|
@@ -4728,7 +4814,7 @@ async function listThemes() {
|
|
|
4728
4814
|
return themes;
|
|
4729
4815
|
}
|
|
4730
4816
|
function clearDirectory(dir) {
|
|
4731
|
-
if (
|
|
4817
|
+
if (existsSync7(dir)) {
|
|
4732
4818
|
const entries = readdirSync4(dir, { withFileTypes: true });
|
|
4733
4819
|
for (const entry of entries) {
|
|
4734
4820
|
const fullPath = join5(dir, entry.name);
|
|
@@ -4741,21 +4827,21 @@ function clearDirectory(dir) {
|
|
|
4741
4827
|
}
|
|
4742
4828
|
}
|
|
4743
4829
|
function createSymlink(source, target) {
|
|
4744
|
-
if (
|
|
4830
|
+
if (existsSync7(target)) {
|
|
4745
4831
|
unlinkSync(target);
|
|
4746
4832
|
}
|
|
4747
4833
|
symlinkSync(source, target);
|
|
4748
4834
|
}
|
|
4749
|
-
async function applyTheme(themeName) {
|
|
4835
|
+
async function applyTheme(themeName, saveMapping = false) {
|
|
4750
4836
|
const themeDir = join5(THEMES_DIR, themeName);
|
|
4751
|
-
if (!
|
|
4837
|
+
if (!existsSync7(themeDir)) {
|
|
4752
4838
|
return { output: `Theme '${themeName}' not found`, success: false };
|
|
4753
4839
|
}
|
|
4754
4840
|
await ensureConfigDir();
|
|
4755
4841
|
await ensureDir2(THEME_TARGET_DIR);
|
|
4756
4842
|
const theme = await parseTheme(themeDir, themeName);
|
|
4757
4843
|
clearDirectory(THEME_TARGET_DIR);
|
|
4758
|
-
if (
|
|
4844
|
+
if (existsSync7(BACKGROUNDS_TARGET_DIR)) {
|
|
4759
4845
|
rmSync(BACKGROUNDS_TARGET_DIR, { recursive: true, force: true });
|
|
4760
4846
|
}
|
|
4761
4847
|
const entries = readdirSync4(themeDir, { withFileTypes: true });
|
|
@@ -4770,7 +4856,13 @@ async function applyTheme(themeName) {
|
|
|
4770
4856
|
const backgroundsSource = join5(themeDir, "backgrounds");
|
|
4771
4857
|
createSymlink(backgroundsSource, BACKGROUNDS_TARGET_DIR);
|
|
4772
4858
|
}
|
|
4859
|
+
if (saveMapping) {
|
|
4860
|
+
await setDeviceTheme(themeName);
|
|
4861
|
+
}
|
|
4773
4862
|
let output = `Theme '${theme.name}' applied successfully`;
|
|
4863
|
+
if (saveMapping) {
|
|
4864
|
+
output += ` (saved as device preference for '${getDeviceHostname()}')`;
|
|
4865
|
+
}
|
|
4774
4866
|
if (theme.metadata?.author) {
|
|
4775
4867
|
output += `
|
|
4776
4868
|
Author: ${theme.metadata.author}`;
|
|
@@ -4787,7 +4879,7 @@ Note: This is a light mode theme`;
|
|
|
4787
4879
|
}
|
|
4788
4880
|
async function showThemeInfo(themeName) {
|
|
4789
4881
|
const themeDir = join5(THEMES_DIR, themeName);
|
|
4790
|
-
if (!
|
|
4882
|
+
if (!existsSync7(themeDir)) {
|
|
4791
4883
|
console.error(`${colors5.red}Error: Theme '${themeName}' not found${colors5.reset}`);
|
|
4792
4884
|
process.exit(1);
|
|
4793
4885
|
}
|
|
@@ -4820,48 +4912,134 @@ ${colors5.green}Has wallpapers${colors5.reset}`);
|
|
|
4820
4912
|
console.log(`${colors5.yellow}Light mode theme${colors5.reset}`);
|
|
4821
4913
|
}
|
|
4822
4914
|
}
|
|
4823
|
-
async function runSetTheme(themeName) {
|
|
4824
|
-
return applyTheme(themeName);
|
|
4915
|
+
async function runSetTheme(themeName, saveMapping = false) {
|
|
4916
|
+
return applyTheme(themeName, saveMapping);
|
|
4917
|
+
}
|
|
4918
|
+
function showDeviceMappings() {
|
|
4919
|
+
const mappings = listDeviceMappings();
|
|
4920
|
+
const defaultTheme = getDefaultTheme();
|
|
4921
|
+
const currentDevice = getDeviceHostname();
|
|
4922
|
+
console.log(`${colors5.cyan}Device Theme Mappings${colors5.reset}`);
|
|
4923
|
+
console.log(`Current device: ${colors5.blue}${currentDevice}${colors5.reset}
|
|
4924
|
+
`);
|
|
4925
|
+
if (defaultTheme) {
|
|
4926
|
+
console.log(`Default theme: ${colors5.green}${defaultTheme}${colors5.reset}
|
|
4927
|
+
`);
|
|
4928
|
+
}
|
|
4929
|
+
if (mappings.length === 0) {
|
|
4930
|
+
console.log(`${colors5.dim}No device-specific themes configured.${colors5.reset}`);
|
|
4931
|
+
return;
|
|
4932
|
+
}
|
|
4933
|
+
console.log("Configured devices:");
|
|
4934
|
+
for (const mapping of mappings) {
|
|
4935
|
+
const marker = mapping.isCurrent ? ` ${colors5.green}(current)${colors5.reset}` : "";
|
|
4936
|
+
const date = new Date(mapping.setAt).toLocaleDateString();
|
|
4937
|
+
console.log(` ${colors5.blue}•${colors5.reset} ${mapping.device}${marker}: ${mapping.theme} ${colors5.dim}(set ${date})${colors5.reset}`);
|
|
4938
|
+
}
|
|
4939
|
+
}
|
|
4940
|
+
async function showThemeList() {
|
|
4941
|
+
const themes = await listThemes();
|
|
4942
|
+
const deviceTheme = getDeviceTheme();
|
|
4943
|
+
if (themes.length === 0) {
|
|
4944
|
+
console.log(`${colors5.yellow}No themes available.${colors5.reset}`);
|
|
4945
|
+
console.log(`This system is compatible with omarchy themes.`);
|
|
4946
|
+
console.log(`
|
|
4947
|
+
Add themes to: ${colors5.cyan}~/.config/formalconf/themes/${colors5.reset}`);
|
|
4948
|
+
return;
|
|
4949
|
+
}
|
|
4950
|
+
console.log(`${colors5.cyan}Usage: formalconf theme <theme-name>${colors5.reset}`);
|
|
4951
|
+
console.log(` formalconf theme <theme-name> --save ${colors5.dim}(save as device preference)${colors5.reset}`);
|
|
4952
|
+
console.log(` formalconf theme --apply ${colors5.dim}(apply device's theme)${colors5.reset}`);
|
|
4953
|
+
console.log(` formalconf theme --list-devices ${colors5.dim}(show device mappings)${colors5.reset}`);
|
|
4954
|
+
console.log(` formalconf theme --default <name> ${colors5.dim}(set default theme)${colors5.reset}`);
|
|
4955
|
+
console.log(` formalconf theme --clear-default ${colors5.dim}(remove default theme)${colors5.reset}`);
|
|
4956
|
+
console.log(` formalconf theme --clear ${colors5.dim}(remove device mapping)${colors5.reset}`);
|
|
4957
|
+
console.log(` formalconf theme --info <theme-name> ${colors5.dim}(show theme details)${colors5.reset}
|
|
4958
|
+
`);
|
|
4959
|
+
console.log("Available themes:");
|
|
4960
|
+
for (const theme of themes) {
|
|
4961
|
+
const extras = [];
|
|
4962
|
+
if (theme.hasBackgrounds)
|
|
4963
|
+
extras.push("wallpapers");
|
|
4964
|
+
if (theme.isLightMode)
|
|
4965
|
+
extras.push("light");
|
|
4966
|
+
if (theme.name === deviceTheme)
|
|
4967
|
+
extras.push("device");
|
|
4968
|
+
const suffix = extras.length ? ` ${colors5.dim}(${extras.join(", ")})${colors5.reset}` : "";
|
|
4969
|
+
console.log(` ${colors5.blue}•${colors5.reset} ${theme.name}${suffix}`);
|
|
4970
|
+
}
|
|
4825
4971
|
}
|
|
4826
4972
|
async function main4() {
|
|
4827
4973
|
const { positionals, values } = parseArgs4({
|
|
4828
4974
|
args: process.argv.slice(2),
|
|
4829
4975
|
options: {
|
|
4830
|
-
info: { type: "boolean", short: "i" }
|
|
4976
|
+
info: { type: "boolean", short: "i" },
|
|
4977
|
+
save: { type: "boolean", short: "s" },
|
|
4978
|
+
apply: { type: "boolean", short: "a" },
|
|
4979
|
+
"list-devices": { type: "boolean", short: "l" },
|
|
4980
|
+
default: { type: "string", short: "d" },
|
|
4981
|
+
"clear-default": { type: "boolean" },
|
|
4982
|
+
clear: { type: "boolean", short: "c" }
|
|
4831
4983
|
},
|
|
4832
4984
|
allowPositionals: true
|
|
4833
4985
|
});
|
|
4834
4986
|
const [themeName] = positionals;
|
|
4835
|
-
if (
|
|
4836
|
-
|
|
4837
|
-
|
|
4838
|
-
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
|
|
4842
|
-
|
|
4987
|
+
if (values["list-devices"]) {
|
|
4988
|
+
showDeviceMappings();
|
|
4989
|
+
return;
|
|
4990
|
+
}
|
|
4991
|
+
if (values.clear) {
|
|
4992
|
+
const deviceTheme = getDeviceTheme();
|
|
4993
|
+
if (!deviceTheme) {
|
|
4994
|
+
console.log(`${colors5.yellow}No theme configured for this device.${colors5.reset}`);
|
|
4995
|
+
return;
|
|
4843
4996
|
}
|
|
4844
|
-
|
|
4845
|
-
console.log(
|
|
4846
|
-
|
|
4847
|
-
|
|
4848
|
-
|
|
4849
|
-
|
|
4850
|
-
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
|
|
4854
|
-
|
|
4855
|
-
|
|
4997
|
+
await clearDeviceTheme();
|
|
4998
|
+
console.log(`${colors5.green}Removed theme mapping for '${getDeviceHostname()}'.${colors5.reset}`);
|
|
4999
|
+
return;
|
|
5000
|
+
}
|
|
5001
|
+
if (values["clear-default"]) {
|
|
5002
|
+
await setDefaultTheme(null);
|
|
5003
|
+
console.log(`${colors5.green}Default theme cleared.${colors5.reset}`);
|
|
5004
|
+
return;
|
|
5005
|
+
}
|
|
5006
|
+
if (values.default !== undefined) {
|
|
5007
|
+
const themeDir = join5(THEMES_DIR, values.default);
|
|
5008
|
+
if (!existsSync7(themeDir)) {
|
|
5009
|
+
console.error(`${colors5.red}Error: Theme '${values.default}' not found${colors5.reset}`);
|
|
5010
|
+
process.exit(1);
|
|
4856
5011
|
}
|
|
4857
|
-
|
|
5012
|
+
await setDefaultTheme(values.default);
|
|
5013
|
+
console.log(`${colors5.green}Default theme set to '${values.default}'.${colors5.reset}`);
|
|
5014
|
+
return;
|
|
5015
|
+
}
|
|
5016
|
+
if (values.apply) {
|
|
5017
|
+
const deviceTheme = getDeviceTheme();
|
|
5018
|
+
if (!deviceTheme) {
|
|
5019
|
+
console.log(`${colors5.yellow}No theme configured for device '${getDeviceHostname()}'.${colors5.reset}`);
|
|
5020
|
+
console.log(`Use 'formalconf theme <name> --save' to set a device preference.`);
|
|
5021
|
+
return;
|
|
5022
|
+
}
|
|
5023
|
+
const result2 = await applyTheme(deviceTheme);
|
|
5024
|
+
console.log(result2.success ? `${colors5.green}${result2.output}${colors5.reset}` : `${colors5.red}${result2.output}${colors5.reset}`);
|
|
5025
|
+
return;
|
|
5026
|
+
}
|
|
5027
|
+
if (!themeName) {
|
|
5028
|
+
const deviceTheme = getDeviceTheme();
|
|
5029
|
+
if (deviceTheme) {
|
|
5030
|
+
const result2 = await applyTheme(deviceTheme);
|
|
5031
|
+
console.log(result2.success ? `${colors5.green}${result2.output}${colors5.reset}` : `${colors5.red}${result2.output}${colors5.reset}`);
|
|
5032
|
+
} else {
|
|
5033
|
+
await showThemeList();
|
|
5034
|
+
}
|
|
5035
|
+
return;
|
|
4858
5036
|
}
|
|
4859
5037
|
if (values.info) {
|
|
4860
5038
|
await showThemeInfo(themeName);
|
|
4861
|
-
|
|
4862
|
-
const result = await applyTheme(themeName);
|
|
4863
|
-
console.log(result.success ? `${colors5.green}${result.output}${colors5.reset}` : `${colors5.red}${result.output}${colors5.reset}`);
|
|
5039
|
+
return;
|
|
4864
5040
|
}
|
|
5041
|
+
const result = await applyTheme(themeName, values.save ?? false);
|
|
5042
|
+
console.log(result.success ? `${colors5.green}${result.output}${colors5.reset}` : `${colors5.red}${result.output}${colors5.reset}`);
|
|
4865
5043
|
}
|
|
4866
5044
|
var isMainModule4 = process.argv[1]?.includes("set-theme");
|
|
4867
5045
|
if (isMainModule4) {
|
|
@@ -4873,16 +5051,19 @@ import { jsxDEV as jsxDEV19 } from "react/jsx-dev-runtime";
|
|
|
4873
5051
|
function ThemeMenu({ onBack }) {
|
|
4874
5052
|
const [themes, setThemes] = useState10([]);
|
|
4875
5053
|
const [loading, setLoading] = useState10(true);
|
|
5054
|
+
const [deviceTheme, setDeviceThemeName] = useState10(null);
|
|
4876
5055
|
const { state, output, success, isRunning, isResult, execute, reset } = useMenuAction();
|
|
5056
|
+
const hostname2 = getDeviceHostname();
|
|
4877
5057
|
const grid = useThemeGrid({
|
|
4878
5058
|
itemCount: themes.length,
|
|
4879
|
-
onSelect: (index) => applyTheme2(themes[index]),
|
|
5059
|
+
onSelect: (index) => applyTheme2(themes[index], false),
|
|
5060
|
+
onSelectAndSave: (index) => applyTheme2(themes[index], true),
|
|
4880
5061
|
onBack,
|
|
4881
5062
|
enabled: state === "menu" && !loading && themes.length > 0
|
|
4882
5063
|
});
|
|
4883
5064
|
useEffect6(() => {
|
|
4884
5065
|
async function loadThemes() {
|
|
4885
|
-
if (!
|
|
5066
|
+
if (!existsSync8(THEMES_DIR)) {
|
|
4886
5067
|
setThemes([]);
|
|
4887
5068
|
setLoading(false);
|
|
4888
5069
|
return;
|
|
@@ -4897,13 +5078,17 @@ function ThemeMenu({ onBack }) {
|
|
|
4897
5078
|
}
|
|
4898
5079
|
}
|
|
4899
5080
|
setThemes(loadedThemes);
|
|
5081
|
+
setDeviceThemeName(getDeviceTheme());
|
|
4900
5082
|
setLoading(false);
|
|
4901
5083
|
}
|
|
4902
5084
|
loadThemes();
|
|
4903
5085
|
}, []);
|
|
4904
|
-
const applyTheme2 = async (theme) => {
|
|
5086
|
+
const applyTheme2 = async (theme, saveAsDeviceDefault) => {
|
|
4905
5087
|
const themeName = theme.path.split("/").pop();
|
|
4906
|
-
await execute(() => runSetTheme(themeName));
|
|
5088
|
+
await execute(() => runSetTheme(themeName, saveAsDeviceDefault));
|
|
5089
|
+
if (saveAsDeviceDefault) {
|
|
5090
|
+
setDeviceThemeName(themeName);
|
|
5091
|
+
}
|
|
4907
5092
|
};
|
|
4908
5093
|
const visibleThemes = useMemo4(() => {
|
|
4909
5094
|
return themes.slice(grid.visibleStartIndex, grid.visibleEndIndex);
|
|
@@ -4973,7 +5158,8 @@ function ThemeMenu({ onBack }) {
|
|
|
4973
5158
|
children: visibleThemes.map((theme, index) => /* @__PURE__ */ jsxDEV19(ThemeCard, {
|
|
4974
5159
|
theme,
|
|
4975
5160
|
isSelected: grid.visibleStartIndex + index === grid.selectedIndex,
|
|
4976
|
-
width: grid.cardWidth
|
|
5161
|
+
width: grid.cardWidth,
|
|
5162
|
+
isDeviceTheme: theme.name === deviceTheme
|
|
4977
5163
|
}, theme.path, false, undefined, this))
|
|
4978
5164
|
}, undefined, false, undefined, this),
|
|
4979
5165
|
grid.showScrollDown && /* @__PURE__ */ jsxDEV19(Text15, {
|
|
@@ -4988,11 +5174,21 @@ function ThemeMenu({ onBack }) {
|
|
|
4988
5174
|
}, undefined, true, undefined, this),
|
|
4989
5175
|
/* @__PURE__ */ jsxDEV19(Box16, {
|
|
4990
5176
|
marginTop: 1,
|
|
4991
|
-
|
|
4992
|
-
|
|
4993
|
-
|
|
4994
|
-
|
|
4995
|
-
|
|
5177
|
+
flexDirection: "column",
|
|
5178
|
+
children: [
|
|
5179
|
+
/* @__PURE__ */ jsxDEV19(Text15, {
|
|
5180
|
+
dimColor: true,
|
|
5181
|
+
children: "←→↑↓/hjkl navigate • Enter apply • Shift+Enter save as device default • Esc back"
|
|
5182
|
+
}, undefined, false, undefined, this),
|
|
5183
|
+
/* @__PURE__ */ jsxDEV19(Text15, {
|
|
5184
|
+
dimColor: true,
|
|
5185
|
+
children: [
|
|
5186
|
+
"Device: ",
|
|
5187
|
+
hostname2
|
|
5188
|
+
]
|
|
5189
|
+
}, undefined, true, undefined, this)
|
|
5190
|
+
]
|
|
5191
|
+
}, undefined, true, undefined, this)
|
|
4996
5192
|
]
|
|
4997
5193
|
}, undefined, true, undefined, this);
|
|
4998
5194
|
}
|