@daliovic/cc-statusline 1.2.0 → 1.3.0
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/README.md +9 -0
- package/dist/config.js +13 -0
- package/dist/prayer.js +24 -2
- package/dist/wizard.js +298 -180
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -96,6 +96,15 @@ Supported calculation methods:
|
|
|
96
96
|
| 12 | UOIF France |
|
|
97
97
|
| 13 | Diyanet Turkey |
|
|
98
98
|
| 14 | Spiritual Administration of Muslims of Russia |
|
|
99
|
+
| 15 | Moonsighting Committee Worldwide |
|
|
100
|
+
| 16 | Dubai (experimental) |
|
|
101
|
+
| 17 | JAKIM, Malaysia |
|
|
102
|
+
| 18 | Tunisia |
|
|
103
|
+
| 19 | Algeria |
|
|
104
|
+
| 20 | KEMENAG, Indonesia |
|
|
105
|
+
| 21 | Morocco |
|
|
106
|
+
| 22 | Comunidade Islamica de Lisboa |
|
|
107
|
+
| 23 | Ministry of Awqaf, Jordan |
|
|
99
108
|
|
|
100
109
|
### Environment Variables
|
|
101
110
|
|
package/dist/config.js
CHANGED
|
@@ -18,6 +18,15 @@ export const PRAYER_METHODS = {
|
|
|
18
18
|
12: "Union Organization Islamic de France",
|
|
19
19
|
13: "Diyanet İşleri Başkanlığı, Turkey",
|
|
20
20
|
14: "Spiritual Administration of Muslims of Russia",
|
|
21
|
+
15: "Moonsighting Committee Worldwide",
|
|
22
|
+
16: "Dubai (experimental)",
|
|
23
|
+
17: "JAKIM, Malaysia",
|
|
24
|
+
18: "Tunisia",
|
|
25
|
+
19: "Algeria",
|
|
26
|
+
20: "KEMENAG, Indonesia",
|
|
27
|
+
21: "Morocco",
|
|
28
|
+
22: "Comunidade Islamica de Lisboa",
|
|
29
|
+
23: "Ministry of Awqaf, Jordan",
|
|
21
30
|
};
|
|
22
31
|
export const DEFAULT_CONFIG = {
|
|
23
32
|
show: {
|
|
@@ -32,6 +41,9 @@ export const DEFAULT_CONFIG = {
|
|
|
32
41
|
contextWarning: 75,
|
|
33
42
|
cacheTtlMs: 300000,
|
|
34
43
|
},
|
|
44
|
+
wizard: {
|
|
45
|
+
autosave: true,
|
|
46
|
+
},
|
|
35
47
|
colors: {
|
|
36
48
|
model: 36, // cyan
|
|
37
49
|
context: 248, // gray
|
|
@@ -57,6 +69,7 @@ export function loadConfig() {
|
|
|
57
69
|
return {
|
|
58
70
|
show: { ...DEFAULT_CONFIG.show, ...loaded.show },
|
|
59
71
|
thresholds: { ...DEFAULT_CONFIG.thresholds, ...loaded.thresholds },
|
|
72
|
+
wizard: { ...DEFAULT_CONFIG.wizard, ...loaded.wizard },
|
|
60
73
|
colors: { ...DEFAULT_CONFIG.colors, ...loaded.colors },
|
|
61
74
|
prayer: { ...DEFAULT_CONFIG.prayer, ...loaded.prayer },
|
|
62
75
|
};
|
package/dist/prayer.js
CHANGED
|
@@ -24,11 +24,33 @@ function formatTimeLeft(diffMs) {
|
|
|
24
24
|
}
|
|
25
25
|
async function getLocationFromIP() {
|
|
26
26
|
try {
|
|
27
|
-
const res = await fetch("http://ip-api.com/json/?fields=lat,lon");
|
|
27
|
+
const res = await fetch("http://ip-api.com/json/?fields=lat,lon,city,country");
|
|
28
28
|
if (!res.ok)
|
|
29
29
|
return null;
|
|
30
30
|
const data = await res.json();
|
|
31
|
-
return { latitude: data.lat, longitude: data.lon };
|
|
31
|
+
return { latitude: data.lat, longitude: data.lon, city: data.city, country: data.country };
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export async function geocodeCity(city, country) {
|
|
38
|
+
try {
|
|
39
|
+
const query = encodeURIComponent(`${city}, ${country}`);
|
|
40
|
+
const res = await fetch(`https://nominatim.openstreetmap.org/search?q=${query}&format=json&limit=1`, {
|
|
41
|
+
headers: { "User-Agent": "cc-statusline/1.0" },
|
|
42
|
+
});
|
|
43
|
+
if (!res.ok)
|
|
44
|
+
return null;
|
|
45
|
+
const data = await res.json();
|
|
46
|
+
if (!data.length)
|
|
47
|
+
return null;
|
|
48
|
+
return {
|
|
49
|
+
latitude: parseFloat(data[0].lat),
|
|
50
|
+
longitude: parseFloat(data[0].lon),
|
|
51
|
+
city,
|
|
52
|
+
country,
|
|
53
|
+
};
|
|
32
54
|
}
|
|
33
55
|
catch {
|
|
34
56
|
return null;
|
package/dist/wizard.js
CHANGED
|
@@ -4,6 +4,14 @@ import { DEFAULT_CONFIG, loadConfig, saveConfig, CONFIG_PATH, PRAYER_METHODS } f
|
|
|
4
4
|
function colorize(code, text) {
|
|
5
5
|
return `\x1b[38;5;${code}m${text}\x1b[0m`;
|
|
6
6
|
}
|
|
7
|
+
// Handle Ctrl+C cancellation
|
|
8
|
+
function isCancelled(error) {
|
|
9
|
+
if (!(error instanceof Error))
|
|
10
|
+
return false;
|
|
11
|
+
return error.name === "ExitPromptError" ||
|
|
12
|
+
error.name === "AbortError" ||
|
|
13
|
+
error.message.includes("force closed");
|
|
14
|
+
}
|
|
7
15
|
function showPreview(config) {
|
|
8
16
|
const c = config.colors;
|
|
9
17
|
const parts = [];
|
|
@@ -31,211 +39,321 @@ function showPreview(config) {
|
|
|
31
39
|
}
|
|
32
40
|
console.log("\n Preview: " + parts.join(" \x1b[2m\u{2502}\x1b[0m ") + "\n");
|
|
33
41
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
{ name: "7-day usage limit", value: "usage7day", checked: config.show.usage7day },
|
|
40
|
-
{ name: "Budget delta arrows", value: "delta", checked: config.show.delta },
|
|
41
|
-
{ name: "Prayer times", value: "prayer", checked: config.show.prayer },
|
|
42
|
-
];
|
|
43
|
-
const selected = await checkbox({
|
|
44
|
-
message: "Toggle items to show (space to toggle, enter to confirm)",
|
|
45
|
-
choices,
|
|
46
|
-
});
|
|
47
|
-
config.show.model = selected.includes("model");
|
|
48
|
-
config.show.context = selected.includes("context");
|
|
49
|
-
config.show.usage5hr = selected.includes("usage5hr");
|
|
50
|
-
config.show.usage7day = selected.includes("usage7day");
|
|
51
|
-
config.show.delta = selected.includes("delta");
|
|
52
|
-
config.show.prayer = selected.includes("prayer");
|
|
42
|
+
function autoSave(config) {
|
|
43
|
+
if (config.wizard.autosave) {
|
|
44
|
+
saveConfig(config);
|
|
45
|
+
console.log(" \x1b[2m(autosaved)\x1b[0m");
|
|
46
|
+
}
|
|
53
47
|
}
|
|
54
|
-
async function
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
message: "Select color to change (ANSI 256 codes: 0-255)",
|
|
68
|
-
choices: colorOptions,
|
|
69
|
-
});
|
|
70
|
-
if (choice === "back")
|
|
71
|
-
break;
|
|
72
|
-
const current = config.colors[choice];
|
|
73
|
-
const newValue = await input({
|
|
74
|
-
message: `Enter ANSI color code (0-255, current: ${colorize(current, String(current))})`,
|
|
75
|
-
default: String(current),
|
|
76
|
-
validate: (val) => {
|
|
77
|
-
const num = parseInt(val, 10);
|
|
78
|
-
if (isNaN(num) || num < 0 || num > 255)
|
|
79
|
-
return "Enter a number 0-255";
|
|
80
|
-
return true;
|
|
81
|
-
},
|
|
48
|
+
async function visibilityMenu(config) {
|
|
49
|
+
try {
|
|
50
|
+
const choices = [
|
|
51
|
+
{ name: "Model indicator", value: "model", checked: config.show.model },
|
|
52
|
+
{ name: "Context usage", value: "context", checked: config.show.context },
|
|
53
|
+
{ name: "5-hour usage limit", value: "usage5hr", checked: config.show.usage5hr },
|
|
54
|
+
{ name: "7-day usage limit", value: "usage7day", checked: config.show.usage7day },
|
|
55
|
+
{ name: "Budget delta arrows", value: "delta", checked: config.show.delta },
|
|
56
|
+
{ name: "Prayer times", value: "prayer", checked: config.show.prayer },
|
|
57
|
+
];
|
|
58
|
+
const selected = await checkbox({
|
|
59
|
+
message: "Toggle items (space=toggle, enter=confirm, ctrl+c=back)",
|
|
60
|
+
choices,
|
|
82
61
|
});
|
|
83
|
-
config.
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
62
|
+
config.show.model = selected.includes("model");
|
|
63
|
+
config.show.context = selected.includes("context");
|
|
64
|
+
config.show.usage5hr = selected.includes("usage5hr");
|
|
65
|
+
config.show.usage7day = selected.includes("usage7day");
|
|
66
|
+
config.show.delta = selected.includes("delta");
|
|
67
|
+
config.show.prayer = selected.includes("prayer");
|
|
68
|
+
autoSave(config);
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
catch (e) {
|
|
72
|
+
if (isCancelled(e))
|
|
73
|
+
return true;
|
|
74
|
+
throw e;
|
|
90
75
|
}
|
|
91
76
|
}
|
|
92
|
-
async function
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
});
|
|
109
|
-
if (choice === "back")
|
|
110
|
-
break;
|
|
111
|
-
if (choice === "method") {
|
|
112
|
-
const method = await select({
|
|
113
|
-
message: "Select calculation method",
|
|
114
|
-
choices: methodChoices,
|
|
77
|
+
async function colorsMenu(config) {
|
|
78
|
+
try {
|
|
79
|
+
const colorOptions = [
|
|
80
|
+
{ name: `Model (current: ${colorize(config.colors.model, String(config.colors.model))})`, value: "model" },
|
|
81
|
+
{ name: `Context (current: ${colorize(config.colors.context, String(config.colors.context))})`, value: "context" },
|
|
82
|
+
{ name: `Context warning (current: ${colorize(config.colors.contextWarning, String(config.colors.contextWarning))})`, value: "contextWarning" },
|
|
83
|
+
{ name: `Usage (current: ${colorize(config.colors.usage, String(config.colors.usage))})`, value: "usage" },
|
|
84
|
+
{ name: `Delta under budget (current: ${colorize(config.colors.deltaUnder, String(config.colors.deltaUnder))})`, value: "deltaUnder" },
|
|
85
|
+
{ name: `Delta over budget (current: ${colorize(config.colors.deltaOver, String(config.colors.deltaOver))})`, value: "deltaOver" },
|
|
86
|
+
{ name: `Prayer (current: ${colorize(config.colors.prayer, String(config.colors.prayer))})`, value: "prayer" },
|
|
87
|
+
{ name: "\x1b[2m← Back\x1b[0m", value: "back" },
|
|
88
|
+
];
|
|
89
|
+
while (true) {
|
|
90
|
+
const choice = await select({
|
|
91
|
+
message: "Select color to change (0-255)",
|
|
92
|
+
choices: colorOptions,
|
|
115
93
|
});
|
|
116
|
-
if (
|
|
117
|
-
|
|
94
|
+
if (choice === "back")
|
|
95
|
+
return false;
|
|
96
|
+
const current = config.colors[choice];
|
|
97
|
+
const newValue = await input({
|
|
98
|
+
message: `Enter ANSI color code (0-255, current: ${colorize(current, String(current))})`,
|
|
99
|
+
default: String(current),
|
|
100
|
+
validate: (val) => {
|
|
101
|
+
const num = parseInt(val, 10);
|
|
102
|
+
if (isNaN(num) || num < 0 || num > 255)
|
|
103
|
+
return "Enter a number 0-255";
|
|
104
|
+
return true;
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
config.colors[choice] = parseInt(newValue, 10);
|
|
108
|
+
autoSave(config);
|
|
109
|
+
// Update the menu option to show new color
|
|
110
|
+
const idx = colorOptions.findIndex(o => o.value === choice);
|
|
111
|
+
if (idx >= 0) {
|
|
112
|
+
const label = choice.replace(/([A-Z])/g, " $1").toLowerCase();
|
|
113
|
+
colorOptions[idx].name = `${label.charAt(0).toUpperCase() + label.slice(1)} (current: ${colorize(config.colors[choice], newValue)})`;
|
|
118
114
|
}
|
|
119
115
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
116
|
+
}
|
|
117
|
+
catch (e) {
|
|
118
|
+
if (isCancelled(e))
|
|
119
|
+
return true;
|
|
120
|
+
throw e;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
async function prayerMenu(config) {
|
|
124
|
+
try {
|
|
125
|
+
const methodChoices = Object.entries(PRAYER_METHODS).map(([code, name]) => ({
|
|
126
|
+
name: `${name}${Number(code) === config.prayer.method ? " (current)" : ""}`,
|
|
127
|
+
value: code,
|
|
128
|
+
}));
|
|
129
|
+
methodChoices.push({ name: "\x1b[2m← Back\x1b[0m", value: "back" });
|
|
130
|
+
while (true) {
|
|
131
|
+
const locationDisplay = config.prayer.location
|
|
132
|
+
? config.prayer.location.city
|
|
133
|
+
? `${config.prayer.location.city}, ${config.prayer.location.country}`
|
|
134
|
+
: `${config.prayer.location.latitude.toFixed(2)}, ${config.prayer.location.longitude.toFixed(2)}`
|
|
135
|
+
: "Auto-detect (IP)";
|
|
136
|
+
const choice = await select({
|
|
137
|
+
message: "Prayer settings",
|
|
123
138
|
choices: [
|
|
124
|
-
{ name:
|
|
125
|
-
{ name:
|
|
139
|
+
{ name: `Calculation method: ${PRAYER_METHODS[config.prayer.method]}`, value: "method" },
|
|
140
|
+
{ name: `Location: ${locationDisplay}`, value: "location" },
|
|
141
|
+
{ name: "\x1b[2m← Back\x1b[0m", value: "back" },
|
|
126
142
|
],
|
|
127
143
|
});
|
|
128
|
-
if (
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
default: config.prayer.location?.latitude?.toString() || "",
|
|
135
|
-
validate: (val) => {
|
|
136
|
-
const num = parseFloat(val);
|
|
137
|
-
if (isNaN(num) || num < -90 || num > 90)
|
|
138
|
-
return "Enter -90 to 90";
|
|
139
|
-
return true;
|
|
140
|
-
},
|
|
144
|
+
if (choice === "back")
|
|
145
|
+
return false;
|
|
146
|
+
if (choice === "method") {
|
|
147
|
+
const method = await select({
|
|
148
|
+
message: "Select calculation method",
|
|
149
|
+
choices: methodChoices,
|
|
141
150
|
});
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
+
if (method !== "back") {
|
|
152
|
+
config.prayer.method = Number(method);
|
|
153
|
+
autoSave(config);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
else if (choice === "location") {
|
|
157
|
+
const locChoice = await select({
|
|
158
|
+
message: "Location setting",
|
|
159
|
+
choices: [
|
|
160
|
+
{ name: "Auto-detect from IP (recommended)", value: "auto" },
|
|
161
|
+
{ name: "Enter city and country", value: "city" },
|
|
162
|
+
{ name: "Enter coordinates manually", value: "coords" },
|
|
163
|
+
],
|
|
151
164
|
});
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
}
|
|
165
|
+
if (locChoice === "auto") {
|
|
166
|
+
config.prayer.location = null;
|
|
167
|
+
autoSave(config);
|
|
168
|
+
}
|
|
169
|
+
else if (locChoice === "city") {
|
|
170
|
+
const city = await input({
|
|
171
|
+
message: "City name",
|
|
172
|
+
default: config.prayer.location?.city || "",
|
|
173
|
+
validate: (val) => val.trim() ? true : "Enter a city name",
|
|
174
|
+
});
|
|
175
|
+
const country = await input({
|
|
176
|
+
message: "Country",
|
|
177
|
+
default: config.prayer.location?.country || "",
|
|
178
|
+
validate: (val) => val.trim() ? true : "Enter a country",
|
|
179
|
+
});
|
|
180
|
+
console.log(" Looking up coordinates...");
|
|
181
|
+
const { geocodeCity } = await import("./prayer.js");
|
|
182
|
+
const location = await geocodeCity(city.trim(), country.trim());
|
|
183
|
+
if (location) {
|
|
184
|
+
config.prayer.location = location;
|
|
185
|
+
console.log(` Found: ${location.latitude.toFixed(4)}, ${location.longitude.toFixed(4)}\n`);
|
|
186
|
+
autoSave(config);
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
console.log(" Could not find location. Please try again or enter coordinates manually.\n");
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
const lat = await input({
|
|
194
|
+
message: "Latitude",
|
|
195
|
+
default: config.prayer.location?.latitude?.toString() || "",
|
|
196
|
+
validate: (val) => {
|
|
197
|
+
const num = parseFloat(val);
|
|
198
|
+
if (isNaN(num) || num < -90 || num > 90)
|
|
199
|
+
return "Enter -90 to 90";
|
|
200
|
+
return true;
|
|
201
|
+
},
|
|
202
|
+
});
|
|
203
|
+
const lng = await input({
|
|
204
|
+
message: "Longitude",
|
|
205
|
+
default: config.prayer.location?.longitude?.toString() || "",
|
|
206
|
+
validate: (val) => {
|
|
207
|
+
const num = parseFloat(val);
|
|
208
|
+
if (isNaN(num) || num < -180 || num > 180)
|
|
209
|
+
return "Enter -180 to 180";
|
|
210
|
+
return true;
|
|
211
|
+
},
|
|
212
|
+
});
|
|
213
|
+
config.prayer.location = {
|
|
214
|
+
latitude: parseFloat(lat),
|
|
215
|
+
longitude: parseFloat(lng),
|
|
216
|
+
};
|
|
217
|
+
autoSave(config);
|
|
218
|
+
}
|
|
156
219
|
}
|
|
157
220
|
}
|
|
158
221
|
}
|
|
222
|
+
catch (e) {
|
|
223
|
+
if (isCancelled(e))
|
|
224
|
+
return true;
|
|
225
|
+
throw e;
|
|
226
|
+
}
|
|
159
227
|
}
|
|
160
228
|
async function thresholdsMenu(config) {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
229
|
+
try {
|
|
230
|
+
const contextWarning = await input({
|
|
231
|
+
message: "Context warning threshold % (turns orange)",
|
|
232
|
+
default: String(config.thresholds.contextWarning),
|
|
233
|
+
validate: (val) => {
|
|
234
|
+
const num = parseInt(val, 10);
|
|
235
|
+
if (isNaN(num) || num < 1 || num > 100)
|
|
236
|
+
return "Enter 1-100";
|
|
237
|
+
return true;
|
|
238
|
+
},
|
|
239
|
+
});
|
|
240
|
+
config.thresholds.contextWarning = parseInt(contextWarning, 10);
|
|
241
|
+
const cacheTtl = await input({
|
|
242
|
+
message: "API cache TTL (milliseconds)",
|
|
243
|
+
default: String(config.thresholds.cacheTtlMs),
|
|
244
|
+
validate: (val) => {
|
|
245
|
+
const num = parseInt(val, 10);
|
|
246
|
+
if (isNaN(num) || num < 0)
|
|
247
|
+
return "Enter a positive number";
|
|
248
|
+
return true;
|
|
249
|
+
},
|
|
250
|
+
});
|
|
251
|
+
config.thresholds.cacheTtlMs = parseInt(cacheTtl, 10);
|
|
252
|
+
autoSave(config);
|
|
253
|
+
return false;
|
|
254
|
+
}
|
|
255
|
+
catch (e) {
|
|
256
|
+
if (isCancelled(e))
|
|
168
257
|
return true;
|
|
169
|
-
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
258
|
+
throw e;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
async function settingsMenu(config) {
|
|
262
|
+
try {
|
|
263
|
+
const autosave = await confirm({
|
|
264
|
+
message: "Enable autosave? (saves after each change)",
|
|
265
|
+
default: config.wizard.autosave,
|
|
266
|
+
});
|
|
267
|
+
config.wizard.autosave = autosave;
|
|
268
|
+
saveConfig(config); // Always save settings changes
|
|
269
|
+
console.log(` Autosave ${autosave ? "enabled" : "disabled"}\n`);
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
catch (e) {
|
|
273
|
+
if (isCancelled(e))
|
|
179
274
|
return true;
|
|
180
|
-
|
|
181
|
-
}
|
|
182
|
-
config.thresholds.cacheTtlMs = parseInt(cacheTtl, 10);
|
|
275
|
+
throw e;
|
|
276
|
+
}
|
|
183
277
|
}
|
|
184
278
|
export async function runWizard() {
|
|
185
|
-
console.log("\n\x1b[1mcc-statusline Configuration\x1b[0m
|
|
279
|
+
console.log("\n\x1b[1mcc-statusline Configuration\x1b[0m");
|
|
280
|
+
console.log("\x1b[2mCtrl+C to go back/exit\x1b[0m\n");
|
|
186
281
|
const config = loadConfig();
|
|
187
282
|
showPreview(config);
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
await colorsMenu(config);
|
|
208
|
-
showPreview(config);
|
|
209
|
-
break;
|
|
210
|
-
case "thresholds":
|
|
211
|
-
await thresholdsMenu(config);
|
|
212
|
-
break;
|
|
213
|
-
case "prayer":
|
|
214
|
-
await prayerMenu(config);
|
|
215
|
-
break;
|
|
216
|
-
case "reset":
|
|
217
|
-
const confirmReset = await confirm({
|
|
218
|
-
message: "Reset all settings to defaults?",
|
|
219
|
-
default: false,
|
|
220
|
-
});
|
|
221
|
-
if (confirmReset) {
|
|
222
|
-
Object.assign(config, JSON.parse(JSON.stringify(DEFAULT_CONFIG)));
|
|
223
|
-
console.log(" Reset to defaults.\n");
|
|
283
|
+
try {
|
|
284
|
+
while (true) {
|
|
285
|
+
const autosaveLabel = config.wizard.autosave ? "\x1b[32m●\x1b[0m" : "\x1b[2m○\x1b[0m";
|
|
286
|
+
const choice = await select({
|
|
287
|
+
message: "What would you like to configure?",
|
|
288
|
+
choices: [
|
|
289
|
+
{ name: "Visibility (show/hide items)", value: "visibility" },
|
|
290
|
+
{ name: "Colors", value: "colors" },
|
|
291
|
+
{ name: "Thresholds", value: "thresholds" },
|
|
292
|
+
{ name: "Prayer settings", value: "prayer" },
|
|
293
|
+
{ name: `Settings ${autosaveLabel} autosave`, value: "settings" },
|
|
294
|
+
{ name: "Reset to defaults", value: "reset" },
|
|
295
|
+
...(config.wizard.autosave ? [] : [{ name: "Save & Exit", value: "save" }]),
|
|
296
|
+
{ name: config.wizard.autosave ? "Exit" : "Exit without saving", value: "exit" },
|
|
297
|
+
],
|
|
298
|
+
});
|
|
299
|
+
switch (choice) {
|
|
300
|
+
case "visibility":
|
|
301
|
+
await visibilityMenu(config);
|
|
224
302
|
showPreview(config);
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
303
|
+
break;
|
|
304
|
+
case "colors":
|
|
305
|
+
await colorsMenu(config);
|
|
306
|
+
showPreview(config);
|
|
307
|
+
break;
|
|
308
|
+
case "thresholds":
|
|
309
|
+
await thresholdsMenu(config);
|
|
310
|
+
break;
|
|
311
|
+
case "prayer":
|
|
312
|
+
await prayerMenu(config);
|
|
313
|
+
break;
|
|
314
|
+
case "settings":
|
|
315
|
+
await settingsMenu(config);
|
|
316
|
+
break;
|
|
317
|
+
case "reset":
|
|
318
|
+
const confirmReset = await confirm({
|
|
319
|
+
message: "Reset all settings to defaults?",
|
|
320
|
+
default: false,
|
|
321
|
+
});
|
|
322
|
+
if (confirmReset) {
|
|
323
|
+
Object.assign(config, JSON.parse(JSON.stringify(DEFAULT_CONFIG)));
|
|
324
|
+
console.log(" Reset to defaults.\n");
|
|
325
|
+
autoSave(config);
|
|
326
|
+
showPreview(config);
|
|
327
|
+
}
|
|
328
|
+
break;
|
|
329
|
+
case "save":
|
|
330
|
+
saveConfig(config);
|
|
331
|
+
console.log(`\n Saved to ${CONFIG_PATH}\n`);
|
|
237
332
|
return;
|
|
238
|
-
|
|
333
|
+
case "exit":
|
|
334
|
+
if (config.wizard.autosave) {
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
const confirmExit = await confirm({
|
|
338
|
+
message: "Exit without saving changes?",
|
|
339
|
+
default: false,
|
|
340
|
+
});
|
|
341
|
+
if (confirmExit)
|
|
342
|
+
return;
|
|
343
|
+
break;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
catch (e) {
|
|
348
|
+
if (isCancelled(e)) {
|
|
349
|
+
if (config.wizard.autosave) {
|
|
350
|
+
console.log("\n \x1b[2mExited (changes autosaved)\x1b[0m\n");
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
console.log("\n \x1b[2mExited without saving\x1b[0m\n");
|
|
354
|
+
}
|
|
355
|
+
return;
|
|
239
356
|
}
|
|
357
|
+
throw e;
|
|
240
358
|
}
|
|
241
359
|
}
|