epoch-tui 0.1.2 → 0.1.3
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/index.js +379 -233
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { render } from "ink";
|
|
5
5
|
|
|
6
6
|
// src/App.tsx
|
|
7
|
-
import { Box as
|
|
7
|
+
import { Box as Box17, Text as Text14 } from "ink";
|
|
8
8
|
|
|
9
9
|
// src/contexts/ThemeContext.tsx
|
|
10
10
|
import { createContext as createContext2, useContext as useContext2, useState as useState2, useEffect as useEffect2 } from "react";
|
|
@@ -1915,8 +1915,8 @@ var ThreeColumnLayout = ({
|
|
|
1915
1915
|
leftPane,
|
|
1916
1916
|
centerPane,
|
|
1917
1917
|
rightPane,
|
|
1918
|
-
leftWidth = "
|
|
1919
|
-
rightWidth = "
|
|
1918
|
+
leftWidth = "20%",
|
|
1919
|
+
rightWidth = "30%",
|
|
1920
1920
|
height,
|
|
1921
1921
|
activePane
|
|
1922
1922
|
}) => {
|
|
@@ -1987,7 +1987,7 @@ var ThreeColumnLayout = ({
|
|
|
1987
1987
|
|
|
1988
1988
|
// src/components/calendar/CalendarPane.tsx
|
|
1989
1989
|
import { useState as useState5, useEffect as useEffect6 } from "react";
|
|
1990
|
-
import { Box as
|
|
1990
|
+
import { Box as Box6, useInput as useInput2 } from "ink";
|
|
1991
1991
|
import { addDays, addWeeks, subDays, subWeeks } from "date-fns";
|
|
1992
1992
|
|
|
1993
1993
|
// src/components/layout/Pane.tsx
|
|
@@ -2092,6 +2092,30 @@ var MonthView = ({ calendarView }) => {
|
|
|
2092
2092
|
] });
|
|
2093
2093
|
};
|
|
2094
2094
|
|
|
2095
|
+
// src/components/common/KeyboardHints.tsx
|
|
2096
|
+
import { Box as Box5, Text as Text3 } from "ink";
|
|
2097
|
+
import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
2098
|
+
var KeyboardHints = ({ hints }) => {
|
|
2099
|
+
const { theme } = useTheme();
|
|
2100
|
+
return /* @__PURE__ */ jsx9(
|
|
2101
|
+
Box5,
|
|
2102
|
+
{
|
|
2103
|
+
marginTop: 1,
|
|
2104
|
+
flexDirection: "row",
|
|
2105
|
+
flexWrap: "wrap",
|
|
2106
|
+
columnGap: 2,
|
|
2107
|
+
width: "100%",
|
|
2108
|
+
children: hints.map((hint, index) => /* @__PURE__ */ jsxs5(Box5, { children: [
|
|
2109
|
+
/* @__PURE__ */ jsx9(Text3, { color: theme.colors.focusIndicator, bold: true, children: hint.key }),
|
|
2110
|
+
/* @__PURE__ */ jsxs5(Text3, { color: theme.colors.keyboardHint, children: [
|
|
2111
|
+
" ",
|
|
2112
|
+
hint.description
|
|
2113
|
+
] })
|
|
2114
|
+
] }, index))
|
|
2115
|
+
}
|
|
2116
|
+
);
|
|
2117
|
+
};
|
|
2118
|
+
|
|
2095
2119
|
// src/utils/date.ts
|
|
2096
2120
|
import { format, startOfMonth, endOfMonth, eachDayOfInterval, startOfWeek, endOfWeek } from "date-fns";
|
|
2097
2121
|
var formatDate = (date, formatStr = "MMM d, yyyy") => {
|
|
@@ -2186,10 +2210,17 @@ var CalendarService = class {
|
|
|
2186
2210
|
var calendarService = new CalendarService();
|
|
2187
2211
|
|
|
2188
2212
|
// src/components/calendar/CalendarPane.tsx
|
|
2189
|
-
import { jsx as
|
|
2213
|
+
import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2190
2214
|
var CalendarPane = () => {
|
|
2191
2215
|
const { theme } = useTheme();
|
|
2192
|
-
const {
|
|
2216
|
+
const {
|
|
2217
|
+
selectedDate,
|
|
2218
|
+
setSelectedDate,
|
|
2219
|
+
tasks,
|
|
2220
|
+
activePane,
|
|
2221
|
+
isModalOpen,
|
|
2222
|
+
isInputMode
|
|
2223
|
+
} = useApp();
|
|
2193
2224
|
const [currentMonth, setCurrentMonth] = useState5({
|
|
2194
2225
|
year: selectedDate.year,
|
|
2195
2226
|
month: selectedDate.month
|
|
@@ -2276,39 +2307,115 @@ var CalendarPane = () => {
|
|
|
2276
2307
|
{ isActive: isFocused && !isInputMode }
|
|
2277
2308
|
);
|
|
2278
2309
|
const monthName = calendarService.getMonthName(currentMonth.month);
|
|
2279
|
-
return /* @__PURE__ */
|
|
2310
|
+
return /* @__PURE__ */ jsx10(
|
|
2280
2311
|
Pane,
|
|
2281
2312
|
{
|
|
2282
2313
|
title: `${monthName} ${currentMonth.year}`,
|
|
2283
2314
|
isFocused,
|
|
2284
2315
|
center: true,
|
|
2285
|
-
children: /* @__PURE__ */
|
|
2286
|
-
/* @__PURE__ */
|
|
2287
|
-
/* @__PURE__ */
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2316
|
+
children: /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", alignItems: "center", children: [
|
|
2317
|
+
/* @__PURE__ */ jsx10(MonthView, { calendarView }),
|
|
2318
|
+
/* @__PURE__ */ jsx10(
|
|
2319
|
+
KeyboardHints,
|
|
2320
|
+
{
|
|
2321
|
+
hints: [
|
|
2322
|
+
{ key: "h/l", description: "days" },
|
|
2323
|
+
{ key: "j/k", description: "weeks" },
|
|
2324
|
+
{ key: "n/p", description: "month" },
|
|
2325
|
+
{ key: "T", description: "today" }
|
|
2326
|
+
]
|
|
2327
|
+
}
|
|
2328
|
+
)
|
|
2291
2329
|
] })
|
|
2292
2330
|
}
|
|
2293
2331
|
);
|
|
2294
2332
|
};
|
|
2295
2333
|
|
|
2296
2334
|
// src/components/tasks/TasksPane.tsx
|
|
2297
|
-
import { useState as useState6, useEffect as
|
|
2298
|
-
import { Box as
|
|
2299
|
-
|
|
2335
|
+
import { useState as useState6, useEffect as useEffect8, useMemo } from "react";
|
|
2336
|
+
import { Box as Box8, Text as Text7, useInput as useInput4 } from "ink";
|
|
2337
|
+
|
|
2338
|
+
// src/components/common/ControlledTextInput.tsx
|
|
2339
|
+
import { useRef as useRef3, useEffect as useEffect7 } from "react";
|
|
2340
|
+
import { Text as Text5, useInput as useInput3 } from "ink";
|
|
2341
|
+
import { jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2342
|
+
var ControlledTextInput = ({
|
|
2343
|
+
value,
|
|
2344
|
+
onChange,
|
|
2345
|
+
onSubmit,
|
|
2346
|
+
onCancel,
|
|
2347
|
+
placeholder,
|
|
2348
|
+
focus = true,
|
|
2349
|
+
placeholderColor,
|
|
2350
|
+
cursorColor = "white",
|
|
2351
|
+
color,
|
|
2352
|
+
maxLength
|
|
2353
|
+
}) => {
|
|
2354
|
+
const pendingValueRef = useRef3(value);
|
|
2355
|
+
const sentValuesRef = useRef3(/* @__PURE__ */ new Set([value]));
|
|
2356
|
+
useEffect7(() => {
|
|
2357
|
+
if (value === pendingValueRef.current) {
|
|
2358
|
+
return;
|
|
2359
|
+
}
|
|
2360
|
+
if (sentValuesRef.current.has(value)) {
|
|
2361
|
+
return;
|
|
2362
|
+
}
|
|
2363
|
+
pendingValueRef.current = value;
|
|
2364
|
+
sentValuesRef.current.clear();
|
|
2365
|
+
sentValuesRef.current.add(value);
|
|
2366
|
+
}, [value]);
|
|
2367
|
+
useInput3(
|
|
2368
|
+
(input, key) => {
|
|
2369
|
+
const currentValue = pendingValueRef.current;
|
|
2370
|
+
if (key.escape) {
|
|
2371
|
+
onCancel?.();
|
|
2372
|
+
return;
|
|
2373
|
+
}
|
|
2374
|
+
if (key.return) {
|
|
2375
|
+
onSubmit(currentValue);
|
|
2376
|
+
return;
|
|
2377
|
+
}
|
|
2378
|
+
if (input === "\r" || input === "\n") return;
|
|
2379
|
+
let nextValue = currentValue;
|
|
2380
|
+
if (key.backspace || key.delete) {
|
|
2381
|
+
nextValue = currentValue.slice(0, -1);
|
|
2382
|
+
} else if (!key.ctrl && !key.meta && input.length > 0) {
|
|
2383
|
+
const filtered = input.replace(/[\x00-\x1F\x7F]/g, "");
|
|
2384
|
+
if (filtered) {
|
|
2385
|
+
const possibleValue = currentValue + filtered;
|
|
2386
|
+
if (maxLength && possibleValue.length > maxLength) {
|
|
2387
|
+
return;
|
|
2388
|
+
}
|
|
2389
|
+
nextValue = possibleValue;
|
|
2390
|
+
}
|
|
2391
|
+
}
|
|
2392
|
+
if (nextValue !== currentValue) {
|
|
2393
|
+
pendingValueRef.current = nextValue;
|
|
2394
|
+
sentValuesRef.current.add(nextValue);
|
|
2395
|
+
onChange(nextValue);
|
|
2396
|
+
}
|
|
2397
|
+
},
|
|
2398
|
+
{ isActive: focus }
|
|
2399
|
+
);
|
|
2400
|
+
const displayValue = pendingValueRef.current || "";
|
|
2401
|
+
const showPlaceholder = !displayValue && placeholder;
|
|
2402
|
+
return /* @__PURE__ */ jsxs7(Text5, { children: [
|
|
2403
|
+
showPlaceholder ? /* @__PURE__ */ jsx11(Text5, { dimColor: true, color: placeholderColor, children: placeholder }) : /* @__PURE__ */ jsx11(Text5, { color, children: displayValue }),
|
|
2404
|
+
focus && /* @__PURE__ */ jsx11(Text5, { backgroundColor: cursorColor, children: " " })
|
|
2405
|
+
] });
|
|
2406
|
+
};
|
|
2300
2407
|
|
|
2301
2408
|
// src/components/tasks/TaskHeader.tsx
|
|
2302
|
-
import { Box as
|
|
2303
|
-
import { jsx as
|
|
2409
|
+
import { Box as Box7, Text as Text6 } from "ink";
|
|
2410
|
+
import { jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2304
2411
|
var TaskHeader = ({
|
|
2305
2412
|
selectedDate,
|
|
2306
2413
|
completionPercentage
|
|
2307
2414
|
}) => {
|
|
2308
2415
|
const { theme } = useTheme();
|
|
2309
|
-
return /* @__PURE__ */
|
|
2310
|
-
/* @__PURE__ */
|
|
2311
|
-
/* @__PURE__ */
|
|
2416
|
+
return /* @__PURE__ */ jsxs8(Box7, { flexDirection: "column", marginBottom: 1, children: [
|
|
2417
|
+
/* @__PURE__ */ jsx12(Text6, { color: theme.colors.taskHeader, children: formatDate(selectedDate, "EEEE, MMMM d, yyyy") }),
|
|
2418
|
+
/* @__PURE__ */ jsxs8(Text6, { color: theme.colors.taskHeader, children: [
|
|
2312
2419
|
completionPercentage,
|
|
2313
2420
|
"% completed"
|
|
2314
2421
|
] })
|
|
@@ -2595,7 +2702,7 @@ var TimelineService = class {
|
|
|
2595
2702
|
var timelineService = new TimelineService();
|
|
2596
2703
|
|
|
2597
2704
|
// src/components/tasks/TasksPane.tsx
|
|
2598
|
-
import { Fragment, jsx as
|
|
2705
|
+
import { Fragment, jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2599
2706
|
var TasksPane = () => {
|
|
2600
2707
|
const {
|
|
2601
2708
|
tasks,
|
|
@@ -2614,8 +2721,6 @@ var TasksPane = () => {
|
|
|
2614
2721
|
const [editMode, setEditMode] = useState6("none");
|
|
2615
2722
|
const [editValue, setEditValue] = useState6("");
|
|
2616
2723
|
const [parentTaskId, setParentTaskId] = useState6(null);
|
|
2617
|
-
const inputValueRef = useRef3("");
|
|
2618
|
-
const [inputKey, setInputKey] = useState6(0);
|
|
2619
2724
|
const [scrollOffset, setScrollOffset] = useState6(0);
|
|
2620
2725
|
const { height: terminalHeight } = useTerminalSize();
|
|
2621
2726
|
const visibleRows = useMemo(() => {
|
|
@@ -2642,48 +2747,55 @@ var TasksPane = () => {
|
|
|
2642
2747
|
}, [dayTasks, expandedIds]);
|
|
2643
2748
|
const selectedTask = flatTasks[selectedIndex]?.task;
|
|
2644
2749
|
const selectedTaskId = selectedTask?.id;
|
|
2645
|
-
|
|
2750
|
+
useEffect8(() => {
|
|
2751
|
+
const allParentIds = /* @__PURE__ */ new Set();
|
|
2752
|
+
const collectParents = (taskList) => {
|
|
2753
|
+
for (const task of taskList) {
|
|
2754
|
+
if (task.children.length > 0) {
|
|
2755
|
+
allParentIds.add(task.id);
|
|
2756
|
+
collectParents(task.children);
|
|
2757
|
+
}
|
|
2758
|
+
}
|
|
2759
|
+
};
|
|
2760
|
+
collectParents(dayTasks);
|
|
2761
|
+
setExpandedIds(allParentIds);
|
|
2762
|
+
}, [dayTasks]);
|
|
2763
|
+
useEffect8(() => {
|
|
2646
2764
|
setSelectedIndex(0);
|
|
2647
2765
|
setEditMode("none");
|
|
2648
2766
|
}, [dateStr]);
|
|
2649
|
-
|
|
2767
|
+
useEffect8(() => {
|
|
2650
2768
|
if (selectedIndex >= flatTasks.length && flatTasks.length > 0) {
|
|
2651
2769
|
setSelectedIndex(flatTasks.length - 1);
|
|
2652
2770
|
}
|
|
2653
2771
|
}, [flatTasks.length, selectedIndex]);
|
|
2654
|
-
|
|
2772
|
+
useEffect8(() => {
|
|
2655
2773
|
if (selectedIndex < scrollOffset) {
|
|
2656
2774
|
setScrollOffset(selectedIndex);
|
|
2657
2775
|
} else if (selectedIndex >= scrollOffset + visibleRows) {
|
|
2658
2776
|
setScrollOffset(selectedIndex - visibleRows + 1);
|
|
2659
2777
|
}
|
|
2660
2778
|
}, [selectedIndex, visibleRows, scrollOffset]);
|
|
2661
|
-
|
|
2779
|
+
useEffect8(() => {
|
|
2662
2780
|
setScrollOffset(0);
|
|
2663
2781
|
}, [dateStr]);
|
|
2664
2782
|
const handleAddTask = () => {
|
|
2665
|
-
inputValueRef.current = "";
|
|
2666
2783
|
setEditMode("add");
|
|
2667
2784
|
setEditValue("");
|
|
2668
|
-
setInputKey((k) => k + 1);
|
|
2669
2785
|
setIsInputMode(true);
|
|
2670
2786
|
};
|
|
2671
2787
|
const handleEditTask = () => {
|
|
2672
2788
|
if (selectedTask) {
|
|
2673
|
-
inputValueRef.current = selectedTask.title;
|
|
2674
2789
|
setEditMode("edit");
|
|
2675
2790
|
setEditValue(selectedTask.title);
|
|
2676
|
-
setInputKey((k) => k + 1);
|
|
2677
2791
|
setIsInputMode(true);
|
|
2678
2792
|
}
|
|
2679
2793
|
};
|
|
2680
2794
|
const handleAddSubtask = () => {
|
|
2681
2795
|
if (selectedTask) {
|
|
2682
|
-
inputValueRef.current = "";
|
|
2683
2796
|
setEditMode("addSubtask");
|
|
2684
2797
|
setEditValue("");
|
|
2685
2798
|
setParentTaskId(selectedTask.id);
|
|
2686
|
-
setInputKey((k) => k + 1);
|
|
2687
2799
|
setIsInputMode(true);
|
|
2688
2800
|
setExpandedIds((prev) => new Set(prev).add(selectedTask.id));
|
|
2689
2801
|
}
|
|
@@ -2847,15 +2959,7 @@ var TasksPane = () => {
|
|
|
2847
2959
|
const handleCollapseAll = () => {
|
|
2848
2960
|
setExpandedIds(/* @__PURE__ */ new Set());
|
|
2849
2961
|
};
|
|
2850
|
-
|
|
2851
|
-
(_input, key) => {
|
|
2852
|
-
if (key.escape) {
|
|
2853
|
-
handleCancelEdit();
|
|
2854
|
-
}
|
|
2855
|
-
},
|
|
2856
|
-
{ isActive: isFocused && editMode !== "none" }
|
|
2857
|
-
);
|
|
2858
|
-
useInput3(
|
|
2962
|
+
useInput4(
|
|
2859
2963
|
(input, key) => {
|
|
2860
2964
|
if ((key.meta || key.ctrl) && (input === "a" || key.leftArrow)) {
|
|
2861
2965
|
handleCollapseAll();
|
|
@@ -2950,92 +3054,95 @@ var TasksPane = () => {
|
|
|
2950
3054
|
},
|
|
2951
3055
|
{ isActive: isFocused && editMode === "none" }
|
|
2952
3056
|
);
|
|
2953
|
-
return /* @__PURE__ */
|
|
2954
|
-
/* @__PURE__ */
|
|
3057
|
+
return /* @__PURE__ */ jsx13(Pane, { title: "Tasks", isFocused, children: /* @__PURE__ */ jsxs9(Box8, { flexDirection: "column", flexGrow: 1, width: "100%", children: [
|
|
3058
|
+
/* @__PURE__ */ jsx13(
|
|
2955
3059
|
TaskHeader,
|
|
2956
3060
|
{
|
|
2957
3061
|
selectedDate: new Date(selectedDate.year, selectedDate.month, selectedDate.day),
|
|
2958
3062
|
completionPercentage: stats.percentage
|
|
2959
3063
|
}
|
|
2960
3064
|
),
|
|
2961
|
-
editMode === "add" && /* @__PURE__ */
|
|
2962
|
-
/* @__PURE__ */
|
|
2963
|
-
/* @__PURE__ */
|
|
2964
|
-
|
|
3065
|
+
editMode === "add" && /* @__PURE__ */ jsxs9(Box8, { marginY: 1, children: [
|
|
3066
|
+
/* @__PURE__ */ jsx13(Text7, { color: theme.colors.focusIndicator, children: "> " }),
|
|
3067
|
+
/* @__PURE__ */ jsx13(
|
|
3068
|
+
ControlledTextInput,
|
|
2965
3069
|
{
|
|
2966
|
-
|
|
3070
|
+
value: editValue,
|
|
2967
3071
|
placeholder: "Enter task name...",
|
|
2968
|
-
onChange:
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
3072
|
+
onChange: setEditValue,
|
|
3073
|
+
onSubmit: handleSubmitEdit,
|
|
3074
|
+
onCancel: handleCancelEdit,
|
|
3075
|
+
color: theme.colors.foreground,
|
|
3076
|
+
placeholderColor: theme.colors.foreground,
|
|
3077
|
+
maxLength: 60
|
|
3078
|
+
}
|
|
2974
3079
|
)
|
|
2975
3080
|
] }),
|
|
2976
|
-
editMode === "addSubtask" && /* @__PURE__ */
|
|
2977
|
-
/* @__PURE__ */
|
|
2978
|
-
/* @__PURE__ */
|
|
2979
|
-
/* @__PURE__ */
|
|
2980
|
-
|
|
3081
|
+
editMode === "addSubtask" && /* @__PURE__ */ jsxs9(Box8, { marginY: 1, children: [
|
|
3082
|
+
/* @__PURE__ */ jsx13(Text7, { color: theme.colors.focusIndicator, children: "> " }),
|
|
3083
|
+
/* @__PURE__ */ jsx13(Text7, { color: theme.colors.keyboardHint, children: " " }),
|
|
3084
|
+
/* @__PURE__ */ jsx13(
|
|
3085
|
+
ControlledTextInput,
|
|
2981
3086
|
{
|
|
2982
|
-
|
|
3087
|
+
value: editValue,
|
|
2983
3088
|
placeholder: "Enter subtask name...",
|
|
2984
|
-
onChange:
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
3089
|
+
onChange: setEditValue,
|
|
3090
|
+
onSubmit: handleSubmitEdit,
|
|
3091
|
+
onCancel: handleCancelEdit,
|
|
3092
|
+
color: theme.colors.foreground,
|
|
3093
|
+
placeholderColor: theme.colors.foreground,
|
|
3094
|
+
maxLength: 60
|
|
3095
|
+
}
|
|
2990
3096
|
)
|
|
2991
3097
|
] }),
|
|
2992
|
-
dayTasks.length === 0 && editMode !== "add" && editMode !== "addSubtask" ? /* @__PURE__ */
|
|
2993
|
-
scrollOffset > 0 && /* @__PURE__ */
|
|
3098
|
+
dayTasks.length === 0 && editMode !== "add" && editMode !== "addSubtask" ? /* @__PURE__ */ jsx13(Box8, { marginY: 1, children: /* @__PURE__ */ jsx13(Text7, { color: theme.colors.keyboardHint, dimColor: true, children: "No tasks. Press 'a' to add one." }) }) : /* @__PURE__ */ jsxs9(Box8, { flexDirection: "column", marginY: 1, paddingRight: 2, children: [
|
|
3099
|
+
scrollOffset > 0 && /* @__PURE__ */ jsx13(Box8, { justifyContent: "center", marginBottom: 1, children: /* @__PURE__ */ jsx13(Text7, { color: theme.colors.keyboardHint, dimColor: true, children: "-- more above --" }) }),
|
|
2994
3100
|
flatTasks.slice(scrollOffset, scrollOffset + visibleRows).map(({ task, depth }, sliceIndex) => {
|
|
2995
3101
|
const index = scrollOffset + sliceIndex;
|
|
2996
3102
|
const isSelected = index === selectedIndex;
|
|
2997
3103
|
const isExpanded = expandedIds.has(task.id);
|
|
2998
3104
|
const isEditing = editMode === "edit" && isSelected;
|
|
2999
3105
|
if (isEditing) {
|
|
3000
|
-
return /* @__PURE__ */
|
|
3001
|
-
/* @__PURE__ */
|
|
3002
|
-
/* @__PURE__ */
|
|
3003
|
-
|
|
3106
|
+
return /* @__PURE__ */ jsxs9(Box8, { children: [
|
|
3107
|
+
/* @__PURE__ */ jsx13(Text7, { color: theme.colors.focusIndicator, children: "> " }),
|
|
3108
|
+
/* @__PURE__ */ jsx13(
|
|
3109
|
+
ControlledTextInput,
|
|
3004
3110
|
{
|
|
3005
|
-
|
|
3006
|
-
onChange:
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3111
|
+
value: editValue,
|
|
3112
|
+
onChange: setEditValue,
|
|
3113
|
+
onSubmit: handleSubmitEdit,
|
|
3114
|
+
onCancel: handleCancelEdit,
|
|
3115
|
+
color: theme.colors.foreground,
|
|
3116
|
+
placeholderColor: theme.colors.foreground,
|
|
3117
|
+
maxLength: 60
|
|
3118
|
+
}
|
|
3012
3119
|
)
|
|
3013
3120
|
] }, task.id);
|
|
3014
3121
|
}
|
|
3015
|
-
return /* @__PURE__ */
|
|
3016
|
-
/* @__PURE__ */
|
|
3017
|
-
|
|
3122
|
+
return /* @__PURE__ */ jsxs9(Box8, { children: [
|
|
3123
|
+
/* @__PURE__ */ jsx13(
|
|
3124
|
+
Text7,
|
|
3018
3125
|
{
|
|
3019
3126
|
color: isSelected ? theme.colors.focusIndicator : theme.colors.foreground,
|
|
3020
3127
|
children: isSelected ? ">" : " "
|
|
3021
3128
|
}
|
|
3022
3129
|
),
|
|
3023
|
-
/* @__PURE__ */
|
|
3024
|
-
/* @__PURE__ */
|
|
3025
|
-
/* @__PURE__ */
|
|
3026
|
-
|
|
3130
|
+
/* @__PURE__ */ jsx13(Text7, { children: " " }),
|
|
3131
|
+
/* @__PURE__ */ jsx13(Text7, { children: " ".repeat(depth) }),
|
|
3132
|
+
/* @__PURE__ */ jsx13(
|
|
3133
|
+
Text7,
|
|
3027
3134
|
{
|
|
3028
3135
|
color: isSelected ? theme.colors.focusIndicator : getStateColor(task.state, theme),
|
|
3029
3136
|
children: getCheckbox(task.state)
|
|
3030
3137
|
}
|
|
3031
3138
|
),
|
|
3032
|
-
/* @__PURE__ */
|
|
3033
|
-
task.children.length > 0 && /* @__PURE__ */
|
|
3034
|
-
/* @__PURE__ */
|
|
3035
|
-
/* @__PURE__ */
|
|
3139
|
+
/* @__PURE__ */ jsx13(Text7, { children: " " }),
|
|
3140
|
+
task.children.length > 0 && /* @__PURE__ */ jsxs9(Fragment, { children: [
|
|
3141
|
+
/* @__PURE__ */ jsx13(Text7, { children: isExpanded ? "\u25BC" : "\u25B6" }),
|
|
3142
|
+
/* @__PURE__ */ jsx13(Text7, { children: " " })
|
|
3036
3143
|
] }),
|
|
3037
|
-
/* @__PURE__ */
|
|
3038
|
-
|
|
3144
|
+
/* @__PURE__ */ jsx13(
|
|
3145
|
+
Text7,
|
|
3039
3146
|
{
|
|
3040
3147
|
color: isSelected ? theme.colors.focusIndicator : getStateColor(task.state, theme),
|
|
3041
3148
|
strikethrough: task.state === "completed",
|
|
@@ -3043,8 +3150,8 @@ var TasksPane = () => {
|
|
|
3043
3150
|
children: task.title
|
|
3044
3151
|
}
|
|
3045
3152
|
),
|
|
3046
|
-
task.startTime && !task.endTime && /* @__PURE__ */
|
|
3047
|
-
|
|
3153
|
+
task.startTime && !task.endTime && /* @__PURE__ */ jsxs9(
|
|
3154
|
+
Text7,
|
|
3048
3155
|
{
|
|
3049
3156
|
color: isSelected ? theme.colors.focusIndicator : theme.colors.timelineEventStarted,
|
|
3050
3157
|
children: [
|
|
@@ -3055,13 +3162,26 @@ var TasksPane = () => {
|
|
|
3055
3162
|
)
|
|
3056
3163
|
] }, task.id);
|
|
3057
3164
|
}),
|
|
3058
|
-
scrollOffset + visibleRows < flatTasks.length && /* @__PURE__ */
|
|
3165
|
+
scrollOffset + visibleRows < flatTasks.length && /* @__PURE__ */ jsx13(Box8, { justifyContent: "center", marginTop: 1, children: /* @__PURE__ */ jsx13(Text7, { color: theme.colors.keyboardHint, dimColor: true, children: "-- more below --" }) })
|
|
3059
3166
|
] }),
|
|
3060
|
-
/* @__PURE__ */
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3167
|
+
/* @__PURE__ */ jsx13(
|
|
3168
|
+
KeyboardHints,
|
|
3169
|
+
{
|
|
3170
|
+
hints: [
|
|
3171
|
+
{ key: "j/k", description: "navigate" },
|
|
3172
|
+
{ key: "a", description: "add" },
|
|
3173
|
+
{ key: "Tab", description: "add subtask" },
|
|
3174
|
+
{ key: "e", description: "edit" },
|
|
3175
|
+
{ key: "d", description: "delete" },
|
|
3176
|
+
{ key: "Space", description: "complete" },
|
|
3177
|
+
{ key: "D", description: "delegate" },
|
|
3178
|
+
{ key: "x", description: "delay" },
|
|
3179
|
+
{ key: "s", description: "start" },
|
|
3180
|
+
{ key: "\u2190/\u2192", description: "collapse/expand" },
|
|
3181
|
+
{ key: "Cmd+\u2190/\u2192", description: "all" }
|
|
3182
|
+
]
|
|
3183
|
+
}
|
|
3184
|
+
)
|
|
3065
3185
|
] }) });
|
|
3066
3186
|
};
|
|
3067
3187
|
function getCheckbox(state) {
|
|
@@ -3087,12 +3207,12 @@ function getStateColor(state, theme) {
|
|
|
3087
3207
|
}
|
|
3088
3208
|
|
|
3089
3209
|
// src/components/timeline/TimelinePane.tsx
|
|
3090
|
-
import { useState as useState7, useEffect as
|
|
3091
|
-
import { Box as
|
|
3210
|
+
import { useState as useState7, useEffect as useEffect9, useMemo as useMemo2 } from "react";
|
|
3211
|
+
import { Box as Box10, Text as Text9, useInput as useInput5 } from "ink";
|
|
3092
3212
|
|
|
3093
3213
|
// src/components/timeline/TimelineEntry.tsx
|
|
3094
|
-
import { Box as
|
|
3095
|
-
import { jsx as
|
|
3214
|
+
import { Box as Box9, Text as Text8 } from "ink";
|
|
3215
|
+
import { jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
3096
3216
|
var TimelineEntry = ({
|
|
3097
3217
|
event,
|
|
3098
3218
|
isLast,
|
|
@@ -3117,32 +3237,39 @@ var TimelineEntry = ({
|
|
|
3117
3237
|
const isFilledCircle = ["completed", "delegated", "delayed"].includes(
|
|
3118
3238
|
event.type
|
|
3119
3239
|
);
|
|
3120
|
-
return /* @__PURE__ */
|
|
3121
|
-
/* @__PURE__ */
|
|
3122
|
-
/* @__PURE__ */
|
|
3123
|
-
/* @__PURE__ */
|
|
3124
|
-
/* @__PURE__ */
|
|
3125
|
-
/* @__PURE__ */
|
|
3240
|
+
return /* @__PURE__ */ jsxs10(Box9, { flexDirection: "column", children: [
|
|
3241
|
+
/* @__PURE__ */ jsxs10(Box9, { children: [
|
|
3242
|
+
/* @__PURE__ */ jsx14(Box9, { width: 3, justifyContent: "center", children: /* @__PURE__ */ jsx14(Text8, { color, children: isFilledCircle ? "\u25CF" : "\u25CB" }) }),
|
|
3243
|
+
/* @__PURE__ */ jsxs10(Box9, { flexDirection: "column", flexGrow: 1, children: [
|
|
3244
|
+
/* @__PURE__ */ jsx14(Box9, { children: /* @__PURE__ */ jsxs10(Text8, { children: [
|
|
3245
|
+
/* @__PURE__ */ jsxs10(Text8, { color, bold: true, children: [
|
|
3126
3246
|
typeStr,
|
|
3127
3247
|
":"
|
|
3128
3248
|
] }),
|
|
3129
|
-
/* @__PURE__ */
|
|
3249
|
+
/* @__PURE__ */ jsxs10(Text8, { color: theme.colors.foreground, children: [
|
|
3130
3250
|
" ",
|
|
3131
3251
|
event.taskTitle
|
|
3132
3252
|
] })
|
|
3133
3253
|
] }) }),
|
|
3134
|
-
/* @__PURE__ */
|
|
3254
|
+
/* @__PURE__ */ jsx14(Box9, { children: /* @__PURE__ */ jsx14(Text8, { color: theme.colors.keyboardHint, dimColor: true, children: timeStr }) })
|
|
3135
3255
|
] })
|
|
3136
3256
|
] }),
|
|
3137
|
-
!isLast && /* @__PURE__ */
|
|
3257
|
+
!isLast && /* @__PURE__ */ jsx14(Box9, { children: /* @__PURE__ */ jsx14(Box9, { width: 3, justifyContent: "center", children: /* @__PURE__ */ jsx14(Text8, { color: hasNextSameTask ? color : theme.colors.border, children: "\u2502" }) }) })
|
|
3138
3258
|
] });
|
|
3139
3259
|
};
|
|
3140
3260
|
|
|
3141
3261
|
// src/components/timeline/TimelinePane.tsx
|
|
3142
|
-
import { jsx as
|
|
3262
|
+
import { jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
3143
3263
|
var TimelinePane = () => {
|
|
3144
3264
|
const { theme } = useTheme();
|
|
3145
|
-
const {
|
|
3265
|
+
const {
|
|
3266
|
+
selectedDate,
|
|
3267
|
+
timeline,
|
|
3268
|
+
setTimeline,
|
|
3269
|
+
activePane,
|
|
3270
|
+
isModalOpen,
|
|
3271
|
+
isInputMode
|
|
3272
|
+
} = useApp();
|
|
3146
3273
|
const isFocused = activePane === "timeline" && !isModalOpen;
|
|
3147
3274
|
const [scrollOffset, setScrollOffset] = useState7(0);
|
|
3148
3275
|
const { height: terminalHeight } = useTerminalSize();
|
|
@@ -3172,10 +3299,10 @@ var TimelinePane = () => {
|
|
|
3172
3299
|
);
|
|
3173
3300
|
return taskGroups.flatMap(([, events]) => events);
|
|
3174
3301
|
}, [dayEvents]);
|
|
3175
|
-
|
|
3302
|
+
useEffect9(() => {
|
|
3176
3303
|
setScrollOffset(0);
|
|
3177
3304
|
}, [dateStr]);
|
|
3178
|
-
|
|
3305
|
+
useInput5(
|
|
3179
3306
|
(input, key) => {
|
|
3180
3307
|
if (!isFocused) return;
|
|
3181
3308
|
if (input === "j" || key.downArrow) {
|
|
@@ -3199,6 +3326,12 @@ var TimelinePane = () => {
|
|
|
3199
3326
|
(prev) => Math.max(prev - Math.floor(visibleRows / 2), 0)
|
|
3200
3327
|
);
|
|
3201
3328
|
}
|
|
3329
|
+
if (input === "C") {
|
|
3330
|
+
setTimeline({
|
|
3331
|
+
...timeline,
|
|
3332
|
+
[dateStr]: []
|
|
3333
|
+
});
|
|
3334
|
+
}
|
|
3202
3335
|
},
|
|
3203
3336
|
{ isActive: isFocused && !isInputMode }
|
|
3204
3337
|
);
|
|
@@ -3208,18 +3341,18 @@ var TimelinePane = () => {
|
|
|
3208
3341
|
);
|
|
3209
3342
|
const canScrollUp = scrollOffset > 0;
|
|
3210
3343
|
const canScrollDown = scrollOffset + visibleRows < sortedEvents.length;
|
|
3211
|
-
return /* @__PURE__ */
|
|
3212
|
-
sortedEvents.length === 0 ? /* @__PURE__ */
|
|
3213
|
-
/* @__PURE__ */
|
|
3214
|
-
/* @__PURE__ */
|
|
3215
|
-
] }) : /* @__PURE__ */
|
|
3216
|
-
canScrollUp && /* @__PURE__ */
|
|
3217
|
-
/* @__PURE__ */
|
|
3344
|
+
return /* @__PURE__ */ jsx15(Pane, { title: "Timeline", isFocused, children: /* @__PURE__ */ jsxs11(Box10, { flexDirection: "column", flexGrow: 1, width: "100%", children: [
|
|
3345
|
+
sortedEvents.length === 0 ? /* @__PURE__ */ jsxs11(Box10, { marginY: 1, flexDirection: "column", children: [
|
|
3346
|
+
/* @__PURE__ */ jsx15(Text9, { color: theme.colors.keyboardHint, dimColor: true, children: "No activities yet." }),
|
|
3347
|
+
/* @__PURE__ */ jsx15(Text9, { color: theme.colors.keyboardHint, dimColor: true, children: "Press 's' to start a task." })
|
|
3348
|
+
] }) : /* @__PURE__ */ jsxs11(Box10, { flexDirection: "column", children: [
|
|
3349
|
+
canScrollUp && /* @__PURE__ */ jsx15(Box10, { justifyContent: "center", marginBottom: 1, children: /* @__PURE__ */ jsx15(Text9, { color: theme.colors.keyboardHint, dimColor: true, children: "-- more above --" }) }),
|
|
3350
|
+
/* @__PURE__ */ jsx15(Box10, { flexDirection: "column", children: visibleEvents.map((event, index) => {
|
|
3218
3351
|
const globalIndex = scrollOffset + index;
|
|
3219
3352
|
const isLast = globalIndex === sortedEvents.length - 1;
|
|
3220
3353
|
const nextEvent = sortedEvents[globalIndex + 1];
|
|
3221
3354
|
const hasNextSameTask = nextEvent && nextEvent.taskId === event.taskId;
|
|
3222
|
-
return /* @__PURE__ */
|
|
3355
|
+
return /* @__PURE__ */ jsx15(
|
|
3223
3356
|
TimelineEntry,
|
|
3224
3357
|
{
|
|
3225
3358
|
event,
|
|
@@ -3229,21 +3362,29 @@ var TimelinePane = () => {
|
|
|
3229
3362
|
event.id
|
|
3230
3363
|
);
|
|
3231
3364
|
}) }),
|
|
3232
|
-
canScrollDown && /* @__PURE__ */
|
|
3365
|
+
canScrollDown && /* @__PURE__ */ jsx15(Box10, { justifyContent: "center", marginTop: 1, children: /* @__PURE__ */ jsx15(Text9, { color: theme.colors.keyboardHint, dimColor: true, children: "-- more below --" }) })
|
|
3233
3366
|
] }),
|
|
3234
|
-
/* @__PURE__ */
|
|
3367
|
+
/* @__PURE__ */ jsx15(
|
|
3368
|
+
KeyboardHints,
|
|
3369
|
+
{
|
|
3370
|
+
hints: [
|
|
3371
|
+
{ key: "j/k", description: "scroll" },
|
|
3372
|
+
{ key: "Shift+C", description: "clear" }
|
|
3373
|
+
]
|
|
3374
|
+
}
|
|
3375
|
+
)
|
|
3235
3376
|
] }) });
|
|
3236
3377
|
};
|
|
3237
3378
|
|
|
3238
3379
|
// src/components/common/HelpDialog.tsx
|
|
3239
|
-
import { Box as
|
|
3380
|
+
import { Box as Box13, Text as Text10 } from "ink";
|
|
3240
3381
|
|
|
3241
3382
|
// src/components/common/Modal.tsx
|
|
3242
|
-
import { Box as
|
|
3383
|
+
import { Box as Box12, useStdout as useStdout3 } from "ink";
|
|
3243
3384
|
|
|
3244
3385
|
// src/components/common/FullscreenBackground.tsx
|
|
3245
|
-
import { Box as
|
|
3246
|
-
import { jsx as
|
|
3386
|
+
import { Box as Box11, useStdout as useStdout2 } from "ink";
|
|
3387
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
3247
3388
|
var FullscreenBackground = ({
|
|
3248
3389
|
children,
|
|
3249
3390
|
backgroundColor
|
|
@@ -3251,8 +3392,8 @@ var FullscreenBackground = ({
|
|
|
3251
3392
|
const { stdout } = useStdout2();
|
|
3252
3393
|
const width = stdout?.columns || 100;
|
|
3253
3394
|
const height = stdout?.rows || 30;
|
|
3254
|
-
return /* @__PURE__ */
|
|
3255
|
-
|
|
3395
|
+
return /* @__PURE__ */ jsx16(
|
|
3396
|
+
Box11,
|
|
3256
3397
|
{
|
|
3257
3398
|
flexDirection: "column",
|
|
3258
3399
|
width,
|
|
@@ -3264,18 +3405,18 @@ var FullscreenBackground = ({
|
|
|
3264
3405
|
};
|
|
3265
3406
|
|
|
3266
3407
|
// src/components/common/Modal.tsx
|
|
3267
|
-
import { jsx as
|
|
3408
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
3268
3409
|
var Modal = ({ children }) => {
|
|
3269
3410
|
const { theme } = useTheme();
|
|
3270
3411
|
const { stdout } = useStdout3();
|
|
3271
3412
|
const width = stdout?.columns || 100;
|
|
3272
3413
|
const height = stdout?.rows || 30;
|
|
3273
|
-
return /* @__PURE__ */
|
|
3414
|
+
return /* @__PURE__ */ jsx17(
|
|
3274
3415
|
FullscreenBackground,
|
|
3275
3416
|
{
|
|
3276
3417
|
backgroundColor: theme.colors.modalOverlay || "black",
|
|
3277
|
-
children: /* @__PURE__ */
|
|
3278
|
-
|
|
3418
|
+
children: /* @__PURE__ */ jsx17(
|
|
3419
|
+
Box12,
|
|
3279
3420
|
{
|
|
3280
3421
|
flexDirection: "column",
|
|
3281
3422
|
width,
|
|
@@ -3290,7 +3431,7 @@ var Modal = ({ children }) => {
|
|
|
3290
3431
|
};
|
|
3291
3432
|
|
|
3292
3433
|
// src/components/common/HelpDialog.tsx
|
|
3293
|
-
import { Fragment as Fragment2, jsx as
|
|
3434
|
+
import { Fragment as Fragment2, jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3294
3435
|
var HelpDialog = () => {
|
|
3295
3436
|
const { theme } = useTheme();
|
|
3296
3437
|
const shortcuts = [
|
|
@@ -3323,8 +3464,8 @@ var HelpDialog = () => {
|
|
|
3323
3464
|
{ key: "j/k", action: "Scroll timeline" },
|
|
3324
3465
|
{ key: "Shift+C", action: "Clear timeline" }
|
|
3325
3466
|
];
|
|
3326
|
-
return /* @__PURE__ */
|
|
3327
|
-
|
|
3467
|
+
return /* @__PURE__ */ jsx18(Modal, { children: /* @__PURE__ */ jsxs12(
|
|
3468
|
+
Box13,
|
|
3328
3469
|
{
|
|
3329
3470
|
flexDirection: "column",
|
|
3330
3471
|
borderStyle: "double",
|
|
@@ -3333,22 +3474,21 @@ var HelpDialog = () => {
|
|
|
3333
3474
|
paddingY: 1,
|
|
3334
3475
|
backgroundColor: theme.colors.modalBackground || theme.colors.background,
|
|
3335
3476
|
children: [
|
|
3336
|
-
/* @__PURE__ */
|
|
3337
|
-
/* @__PURE__ */
|
|
3338
|
-
/* @__PURE__ */
|
|
3339
|
-
/* @__PURE__ */
|
|
3340
|
-
] }) : /* @__PURE__ */
|
|
3341
|
-
/* @__PURE__ */
|
|
3477
|
+
/* @__PURE__ */ jsx18(Text10, { bold: true, color: theme.colors.calendarHeader, children: "Keyboard Shortcuts" }),
|
|
3478
|
+
/* @__PURE__ */ jsx18(Box13, { flexDirection: "column", marginTop: 1, children: shortcuts.map((item, idx) => /* @__PURE__ */ jsx18(Box13, { marginY: 0, children: item.key ? /* @__PURE__ */ jsxs12(Fragment2, { children: [
|
|
3479
|
+
/* @__PURE__ */ jsx18(Box13, { width: 20, children: /* @__PURE__ */ jsx18(Text10, { color: theme.colors.timelineEventStarted, children: item.key }) }),
|
|
3480
|
+
/* @__PURE__ */ jsx18(Text10, { color: theme.colors.foreground, children: item.action })
|
|
3481
|
+
] }) : /* @__PURE__ */ jsx18(Text10, { color: theme.colors.separator, children: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500" }) }, idx)) }),
|
|
3482
|
+
/* @__PURE__ */ jsx18(Box13, { marginY: 1, children: /* @__PURE__ */ jsx18(Text10, { color: theme.colors.keyboardHint, dimColor: true, children: "Press '?' to close" }) })
|
|
3342
3483
|
]
|
|
3343
3484
|
}
|
|
3344
3485
|
) });
|
|
3345
3486
|
};
|
|
3346
3487
|
|
|
3347
3488
|
// src/components/common/ThemeDialog.tsx
|
|
3348
|
-
import { useState as useState8, useMemo as useMemo3, useEffect as
|
|
3349
|
-
import { Box as
|
|
3350
|
-
import
|
|
3351
|
-
import { jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
3489
|
+
import { useState as useState8, useMemo as useMemo3, useEffect as useEffect10 } from "react";
|
|
3490
|
+
import { Box as Box14, Text as Text11, useInput as useInput6 } from "ink";
|
|
3491
|
+
import { jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3352
3492
|
var ThemeDialog = () => {
|
|
3353
3493
|
const { theme, setTheme, themeName } = useTheme();
|
|
3354
3494
|
const { setShowThemeDialog } = useApp();
|
|
@@ -3388,21 +3528,19 @@ var ThemeDialog = () => {
|
|
|
3388
3528
|
return idx >= 0 ? idx : 0;
|
|
3389
3529
|
}, [themeItems, themeName]);
|
|
3390
3530
|
const [selectedIndex, setSelectedIndex] = useState8(initialIndex);
|
|
3391
|
-
|
|
3531
|
+
useEffect10(() => {
|
|
3392
3532
|
setSelectedIndex(0);
|
|
3393
3533
|
}, [searchQuery]);
|
|
3394
|
-
|
|
3534
|
+
useInput6(
|
|
3395
3535
|
(input, key) => {
|
|
3396
3536
|
if (key.escape) {
|
|
3397
3537
|
setShowThemeDialog(false);
|
|
3398
3538
|
return;
|
|
3399
3539
|
}
|
|
3540
|
+
if ((input === "\r" || input === "\n") && !key.return) {
|
|
3541
|
+
return;
|
|
3542
|
+
}
|
|
3400
3543
|
if (focusMode === "search") {
|
|
3401
|
-
if (key.return && themeItems.length > 0) {
|
|
3402
|
-
setTheme(themeItems[0].value);
|
|
3403
|
-
setShowThemeDialog(false);
|
|
3404
|
-
return;
|
|
3405
|
-
}
|
|
3406
3544
|
if (key.downArrow && themeItems.length > 0) {
|
|
3407
3545
|
setFocusMode("list");
|
|
3408
3546
|
setSelectedIndex(0);
|
|
@@ -3436,8 +3574,8 @@ var ThemeDialog = () => {
|
|
|
3436
3574
|
const formatThemeName = (name) => {
|
|
3437
3575
|
return name.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
3438
3576
|
};
|
|
3439
|
-
return /* @__PURE__ */
|
|
3440
|
-
|
|
3577
|
+
return /* @__PURE__ */ jsx19(Modal, { children: /* @__PURE__ */ jsxs13(
|
|
3578
|
+
Box14,
|
|
3441
3579
|
{
|
|
3442
3580
|
flexDirection: "column",
|
|
3443
3581
|
borderStyle: "double",
|
|
@@ -3447,38 +3585,46 @@ var ThemeDialog = () => {
|
|
|
3447
3585
|
width: 44,
|
|
3448
3586
|
backgroundColor: theme.colors.modalBackground || theme.colors.background,
|
|
3449
3587
|
children: [
|
|
3450
|
-
/* @__PURE__ */
|
|
3451
|
-
/* @__PURE__ */
|
|
3452
|
-
/* @__PURE__ */
|
|
3588
|
+
/* @__PURE__ */ jsx19(Text11, { bold: true, color: theme.colors.calendarHeader, underline: true, children: "Select Theme" }),
|
|
3589
|
+
/* @__PURE__ */ jsxs13(Box14, { marginTop: 1, flexDirection: "row", alignItems: "center", children: [
|
|
3590
|
+
/* @__PURE__ */ jsxs13(Text11, { color: theme.colors.foreground, dimColor: true, children: [
|
|
3453
3591
|
"Search:",
|
|
3454
3592
|
" "
|
|
3455
3593
|
] }),
|
|
3456
|
-
/* @__PURE__ */
|
|
3457
|
-
|
|
3594
|
+
/* @__PURE__ */ jsx19(
|
|
3595
|
+
ControlledTextInput,
|
|
3458
3596
|
{
|
|
3459
3597
|
value: searchQuery,
|
|
3460
3598
|
onChange: setSearchQuery,
|
|
3599
|
+
onSubmit: () => {
|
|
3600
|
+
if (themeItems.length > 0) {
|
|
3601
|
+
setTheme(themeItems[0].value);
|
|
3602
|
+
setShowThemeDialog(false);
|
|
3603
|
+
}
|
|
3604
|
+
},
|
|
3461
3605
|
focus: focusMode === "search",
|
|
3462
|
-
placeholder: "Type to filter..."
|
|
3606
|
+
placeholder: "Type to filter...",
|
|
3607
|
+
placeholderColor: theme.colors.foreground,
|
|
3608
|
+
color: theme.colors.foreground
|
|
3463
3609
|
}
|
|
3464
|
-
)
|
|
3610
|
+
)
|
|
3465
3611
|
] }),
|
|
3466
|
-
/* @__PURE__ */
|
|
3612
|
+
/* @__PURE__ */ jsx19(Box14, { flexDirection: "column", marginTop: 1, children: allThemes.map((item, idx) => {
|
|
3467
3613
|
if (item.type === "separator") {
|
|
3468
|
-
return /* @__PURE__ */
|
|
3469
|
-
|
|
3614
|
+
return /* @__PURE__ */ jsx19(
|
|
3615
|
+
Box14,
|
|
3470
3616
|
{
|
|
3471
3617
|
marginTop: idx > 0 ? 1 : 0,
|
|
3472
3618
|
marginBottom: 0,
|
|
3473
|
-
children: /* @__PURE__ */
|
|
3619
|
+
children: /* @__PURE__ */ jsx19(Text11, { bold: true, color: theme.colors.calendarHeader, dimColor: true, children: item.value })
|
|
3474
3620
|
},
|
|
3475
3621
|
`sep-${idx}`
|
|
3476
3622
|
);
|
|
3477
3623
|
}
|
|
3478
3624
|
const isSelected = item.value === selectedThemeName;
|
|
3479
3625
|
const isCurrent = item.value === themeName;
|
|
3480
|
-
return /* @__PURE__ */
|
|
3481
|
-
|
|
3626
|
+
return /* @__PURE__ */ jsx19(Box14, { paddingLeft: 1, children: /* @__PURE__ */ jsxs13(
|
|
3627
|
+
Text11,
|
|
3482
3628
|
{
|
|
3483
3629
|
color: isSelected ? theme.colors.focusIndicator : theme.colors.foreground,
|
|
3484
3630
|
bold: isSelected,
|
|
@@ -3490,16 +3636,16 @@ var ThemeDialog = () => {
|
|
|
3490
3636
|
}
|
|
3491
3637
|
) }, item.value);
|
|
3492
3638
|
}) }),
|
|
3493
|
-
/* @__PURE__ */
|
|
3639
|
+
/* @__PURE__ */ jsx19(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx19(Text11, { color: theme.colors.keyboardHint, dimColor: true, children: focusMode === "search" ? "Type to search \u2022 \u2193 to navigate list \u2022 Esc to close" : "\u2191/\u2193 or k/j to navigate \u2022 Enter to select \u2022 Esc to close" }) })
|
|
3494
3640
|
]
|
|
3495
3641
|
}
|
|
3496
3642
|
) });
|
|
3497
3643
|
};
|
|
3498
3644
|
|
|
3499
3645
|
// src/components/common/ClearTimelineDialog.tsx
|
|
3500
|
-
import { Box as
|
|
3646
|
+
import { Box as Box15, Text as Text12, useInput as useInput7 } from "ink";
|
|
3501
3647
|
import { format as format2 } from "date-fns";
|
|
3502
|
-
import { jsx as
|
|
3648
|
+
import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3503
3649
|
var ClearTimelineDialog = () => {
|
|
3504
3650
|
const { theme } = useTheme();
|
|
3505
3651
|
const {
|
|
@@ -3519,15 +3665,15 @@ var ClearTimelineDialog = () => {
|
|
|
3519
3665
|
const handleCancel = () => {
|
|
3520
3666
|
setShowClearTimelineDialog(false);
|
|
3521
3667
|
};
|
|
3522
|
-
|
|
3668
|
+
useInput7((input, key) => {
|
|
3523
3669
|
if (input.toLowerCase() === "y" || key.return) {
|
|
3524
3670
|
handleConfirm();
|
|
3525
3671
|
} else if (input.toLowerCase() === "n" || key.escape) {
|
|
3526
3672
|
handleCancel();
|
|
3527
3673
|
}
|
|
3528
3674
|
});
|
|
3529
|
-
return /* @__PURE__ */
|
|
3530
|
-
|
|
3675
|
+
return /* @__PURE__ */ jsx20(Modal, { children: /* @__PURE__ */ jsxs14(
|
|
3676
|
+
Box15,
|
|
3531
3677
|
{
|
|
3532
3678
|
flexDirection: "column",
|
|
3533
3679
|
borderStyle: "double",
|
|
@@ -3536,39 +3682,39 @@ var ClearTimelineDialog = () => {
|
|
|
3536
3682
|
paddingY: 2,
|
|
3537
3683
|
backgroundColor: theme.colors.modalBackground || theme.colors.background,
|
|
3538
3684
|
children: [
|
|
3539
|
-
/* @__PURE__ */
|
|
3540
|
-
/* @__PURE__ */
|
|
3541
|
-
/* @__PURE__ */
|
|
3542
|
-
/* @__PURE__ */
|
|
3543
|
-
eventCount > 0 ? /* @__PURE__ */
|
|
3685
|
+
/* @__PURE__ */ jsx20(Box15, { justifyContent: "center", marginBottom: 1, children: /* @__PURE__ */ jsx20(Text12, { bold: true, color: theme.colors.taskStateDelayed, children: "Clear Timeline" }) }),
|
|
3686
|
+
/* @__PURE__ */ jsxs14(Box15, { flexDirection: "column", marginY: 1, children: [
|
|
3687
|
+
/* @__PURE__ */ jsx20(Text12, { color: theme.colors.foreground, children: "You are about to clear the timeline for" }),
|
|
3688
|
+
/* @__PURE__ */ jsx20(Box15, { justifyContent: "center", marginY: 1, children: /* @__PURE__ */ jsx20(Text12, { bold: true, color: theme.colors.calendarHeader, children: formattedDate }) }),
|
|
3689
|
+
eventCount > 0 ? /* @__PURE__ */ jsxs14(Text12, { color: theme.colors.keyboardHint, children: [
|
|
3544
3690
|
"This will remove ",
|
|
3545
3691
|
eventCount,
|
|
3546
3692
|
" event",
|
|
3547
3693
|
eventCount !== 1 ? "s" : "",
|
|
3548
3694
|
" from the timeline."
|
|
3549
|
-
] }) : /* @__PURE__ */
|
|
3695
|
+
] }) : /* @__PURE__ */ jsx20(Text12, { color: theme.colors.keyboardHint, dimColor: true, children: "The timeline is already empty." })
|
|
3550
3696
|
] }),
|
|
3551
|
-
/* @__PURE__ */
|
|
3552
|
-
/* @__PURE__ */
|
|
3553
|
-
/* @__PURE__ */
|
|
3554
|
-
/* @__PURE__ */
|
|
3555
|
-
/* @__PURE__ */
|
|
3697
|
+
/* @__PURE__ */ jsxs14(Box15, { marginTop: 2, justifyContent: "center", children: [
|
|
3698
|
+
/* @__PURE__ */ jsx20(Text12, { color: theme.colors.foreground, children: "Are you sure? " }),
|
|
3699
|
+
/* @__PURE__ */ jsx20(Text12, { color: theme.colors.taskStateCompleted, bold: true, children: "[Y]es" }),
|
|
3700
|
+
/* @__PURE__ */ jsx20(Text12, { color: theme.colors.foreground, children: " / " }),
|
|
3701
|
+
/* @__PURE__ */ jsx20(Text12, { color: theme.colors.taskStateDelayed, bold: true, children: "[N]o" })
|
|
3556
3702
|
] }),
|
|
3557
|
-
/* @__PURE__ */
|
|
3703
|
+
/* @__PURE__ */ jsx20(Box15, { marginTop: 2, justifyContent: "center", children: /* @__PURE__ */ jsx20(Text12, { color: theme.colors.keyboardHint, dimColor: true, children: "Press Y to confirm, N or Esc to cancel" }) })
|
|
3558
3704
|
]
|
|
3559
3705
|
}
|
|
3560
3706
|
) });
|
|
3561
3707
|
};
|
|
3562
3708
|
|
|
3563
3709
|
// src/components/overview/OverviewScreen.tsx
|
|
3564
|
-
import
|
|
3565
|
-
import { Box as
|
|
3710
|
+
import React9, { useMemo as useMemo4 } from "react";
|
|
3711
|
+
import { Box as Box16, Text as Text13, useInput as useInput8 } from "ink";
|
|
3566
3712
|
import { startOfMonth as startOfMonth2, endOfMonth as endOfMonth2, eachDayOfInterval as eachDayOfInterval2 } from "date-fns";
|
|
3567
|
-
import { jsx as
|
|
3713
|
+
import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
3568
3714
|
var OverviewScreen = () => {
|
|
3569
3715
|
const { theme } = useTheme();
|
|
3570
3716
|
const { tasks, overviewMonth, setOverviewMonth, setShowOverview } = useApp();
|
|
3571
|
-
const [scrollOffset, setScrollOffset] =
|
|
3717
|
+
const [scrollOffset, setScrollOffset] = React9.useState(0);
|
|
3572
3718
|
const { height: terminalHeight } = useTerminalSize();
|
|
3573
3719
|
const visibleRows = useMemo4(() => {
|
|
3574
3720
|
return Math.max(2, Math.floor((terminalHeight - 9) / 3));
|
|
@@ -3604,10 +3750,10 @@ var OverviewScreen = () => {
|
|
|
3604
3750
|
setOverviewMonth({ ...overviewMonth, month: newMonth });
|
|
3605
3751
|
}
|
|
3606
3752
|
};
|
|
3607
|
-
|
|
3753
|
+
React9.useEffect(() => {
|
|
3608
3754
|
setScrollOffset(0);
|
|
3609
3755
|
}, [overviewMonth]);
|
|
3610
|
-
|
|
3756
|
+
useInput8((input, key) => {
|
|
3611
3757
|
if (key.escape) {
|
|
3612
3758
|
setShowOverview(false);
|
|
3613
3759
|
return;
|
|
@@ -3643,21 +3789,21 @@ var OverviewScreen = () => {
|
|
|
3643
3789
|
);
|
|
3644
3790
|
const canScrollUp = scrollOffset > 0;
|
|
3645
3791
|
const canScrollDown = scrollOffset + visibleRows < rows;
|
|
3646
|
-
return /* @__PURE__ */
|
|
3647
|
-
/* @__PURE__ */
|
|
3648
|
-
/* @__PURE__ */
|
|
3649
|
-
/* @__PURE__ */
|
|
3792
|
+
return /* @__PURE__ */ jsxs15(Box16, { flexDirection: "column", padding: 1, width: "100%", height: "100%", children: [
|
|
3793
|
+
/* @__PURE__ */ jsxs15(Box16, { flexDirection: "column", marginBottom: 1, children: [
|
|
3794
|
+
/* @__PURE__ */ jsx21(Text13, { bold: true, color: theme.colors.focusIndicator, children: "Overview" }),
|
|
3795
|
+
/* @__PURE__ */ jsx21(Text13, { color: theme.colors.foreground, children: monthName })
|
|
3650
3796
|
] }),
|
|
3651
|
-
/* @__PURE__ */
|
|
3652
|
-
canScrollUp && /* @__PURE__ */
|
|
3797
|
+
/* @__PURE__ */ jsxs15(Box16, { flexDirection: "column", flexGrow: 1, children: [
|
|
3798
|
+
canScrollUp && /* @__PURE__ */ jsx21(Box16, { justifyContent: "center", marginBottom: 1, children: /* @__PURE__ */ jsx21(Text13, { color: theme.colors.keyboardHint, dimColor: true, children: "-- more above --" }) }),
|
|
3653
3799
|
visibleRowData.map((_, index) => {
|
|
3654
3800
|
const rowIndex = scrollOffset + index;
|
|
3655
|
-
return /* @__PURE__ */
|
|
3801
|
+
return /* @__PURE__ */ jsx21(Box16, { flexDirection: "row", marginBottom: 1, children: Array.from({ length: columns }).map((_2, colIndex) => {
|
|
3656
3802
|
const dateIndex = rowIndex * columns + colIndex;
|
|
3657
3803
|
const date = monthDates[dateIndex];
|
|
3658
3804
|
if (!date) {
|
|
3659
|
-
return /* @__PURE__ */
|
|
3660
|
-
|
|
3805
|
+
return /* @__PURE__ */ jsx21(
|
|
3806
|
+
Box16,
|
|
3661
3807
|
{
|
|
3662
3808
|
flexDirection: "column",
|
|
3663
3809
|
flexGrow: 1,
|
|
@@ -3677,17 +3823,17 @@ var OverviewScreen = () => {
|
|
|
3677
3823
|
}
|
|
3678
3824
|
};
|
|
3679
3825
|
traverse(dayTasks, 0);
|
|
3680
|
-
return /* @__PURE__ */
|
|
3681
|
-
|
|
3826
|
+
return /* @__PURE__ */ jsxs15(
|
|
3827
|
+
Box16,
|
|
3682
3828
|
{
|
|
3683
3829
|
flexDirection: "column",
|
|
3684
3830
|
flexGrow: 1,
|
|
3685
3831
|
flexBasis: 0,
|
|
3686
3832
|
marginRight: colIndex === columns - 1 ? 0 : 2,
|
|
3687
3833
|
children: [
|
|
3688
|
-
/* @__PURE__ */
|
|
3689
|
-
/* @__PURE__ */
|
|
3690
|
-
flatTasksWithDepth.length === 0 ? /* @__PURE__ */
|
|
3834
|
+
/* @__PURE__ */ jsx21(Text13, { bold: true, color: theme.colors.calendarSelected, children: formatDate(date, "do MMM") }),
|
|
3835
|
+
/* @__PURE__ */ jsxs15(Box16, { flexDirection: "column", children: [
|
|
3836
|
+
flatTasksWithDepth.length === 0 ? /* @__PURE__ */ jsx21(Text13, { dimColor: true, color: theme.colors.keyboardHint, children: "No tasks" }) : flatTasksWithDepth.slice(0, 10).map(({ task, depth }) => /* @__PURE__ */ jsx21(
|
|
3691
3837
|
TaskItem,
|
|
3692
3838
|
{
|
|
3693
3839
|
task,
|
|
@@ -3696,7 +3842,7 @@ var OverviewScreen = () => {
|
|
|
3696
3842
|
},
|
|
3697
3843
|
task.id
|
|
3698
3844
|
)),
|
|
3699
|
-
flatTasksWithDepth.length > 10 && /* @__PURE__ */
|
|
3845
|
+
flatTasksWithDepth.length > 10 && /* @__PURE__ */ jsxs15(Text13, { dimColor: true, color: theme.colors.keyboardHint, children: [
|
|
3700
3846
|
"+",
|
|
3701
3847
|
flatTasksWithDepth.length - 10,
|
|
3702
3848
|
" more..."
|
|
@@ -3708,22 +3854,22 @@ var OverviewScreen = () => {
|
|
|
3708
3854
|
);
|
|
3709
3855
|
}) }, rowIndex);
|
|
3710
3856
|
}),
|
|
3711
|
-
canScrollDown && /* @__PURE__ */
|
|
3857
|
+
canScrollDown && /* @__PURE__ */ jsx21(Box16, { justifyContent: "center", marginTop: 1, children: /* @__PURE__ */ jsx21(Text13, { color: theme.colors.keyboardHint, dimColor: true, children: "-- more below --" }) })
|
|
3712
3858
|
] }),
|
|
3713
|
-
/* @__PURE__ */
|
|
3859
|
+
/* @__PURE__ */ jsx21(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx21(Text13, { color: theme.colors.keyboardHint, dimColor: true, children: "n/p or \u2190/\u2192: month | j/k or \u2193/\u2191: scroll | Esc: close | Shift+;: toggle" }) })
|
|
3714
3860
|
] });
|
|
3715
3861
|
};
|
|
3716
3862
|
var TaskItem = ({ task, theme, depth }) => {
|
|
3717
3863
|
const checkbox = getCheckbox2(task.state);
|
|
3718
3864
|
const color = getStateColor2(task.state, theme);
|
|
3719
|
-
return /* @__PURE__ */
|
|
3720
|
-
/* @__PURE__ */
|
|
3865
|
+
return /* @__PURE__ */ jsxs15(Box16, { children: [
|
|
3866
|
+
/* @__PURE__ */ jsxs15(Text13, { color, children: [
|
|
3721
3867
|
checkbox,
|
|
3722
3868
|
" "
|
|
3723
3869
|
] }),
|
|
3724
|
-
depth > 0 && /* @__PURE__ */
|
|
3725
|
-
/* @__PURE__ */
|
|
3726
|
-
|
|
3870
|
+
depth > 0 && /* @__PURE__ */ jsx21(Text13, { children: " ".repeat(depth) }),
|
|
3871
|
+
/* @__PURE__ */ jsx21(
|
|
3872
|
+
Text13,
|
|
3727
3873
|
{
|
|
3728
3874
|
color,
|
|
3729
3875
|
strikethrough: task.state === "completed",
|
|
@@ -3756,7 +3902,7 @@ function getStateColor2(state, theme) {
|
|
|
3756
3902
|
}
|
|
3757
3903
|
|
|
3758
3904
|
// src/App.tsx
|
|
3759
|
-
import { jsx as
|
|
3905
|
+
import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
3760
3906
|
var AppContent = () => {
|
|
3761
3907
|
const {
|
|
3762
3908
|
showHelp,
|
|
@@ -3770,26 +3916,26 @@ var AppContent = () => {
|
|
|
3770
3916
|
useKeyboardNav();
|
|
3771
3917
|
const { width, height } = useTerminalSize();
|
|
3772
3918
|
if (showThemeDialog) {
|
|
3773
|
-
return /* @__PURE__ */
|
|
3919
|
+
return /* @__PURE__ */ jsx22(ThemeDialog, {});
|
|
3774
3920
|
}
|
|
3775
3921
|
if (showHelp) {
|
|
3776
|
-
return /* @__PURE__ */
|
|
3922
|
+
return /* @__PURE__ */ jsx22(HelpDialog, {});
|
|
3777
3923
|
}
|
|
3778
3924
|
if (showClearTimelineDialog) {
|
|
3779
|
-
return /* @__PURE__ */
|
|
3925
|
+
return /* @__PURE__ */ jsx22(ClearTimelineDialog, {});
|
|
3780
3926
|
}
|
|
3781
|
-
return /* @__PURE__ */
|
|
3782
|
-
showOverview ? /* @__PURE__ */
|
|
3927
|
+
return /* @__PURE__ */ jsx22(FullscreenBackground, { backgroundColor: theme.colors.background || "black", children: /* @__PURE__ */ jsxs16(Box17, { flexDirection: "column", width, height, padding: 1, backgroundColor: theme.colors.background, children: [
|
|
3928
|
+
showOverview ? /* @__PURE__ */ jsx22(OverviewScreen, {}) : /* @__PURE__ */ jsx22(
|
|
3783
3929
|
ThreeColumnLayout,
|
|
3784
3930
|
{
|
|
3785
|
-
leftPane: /* @__PURE__ */
|
|
3786
|
-
centerPane: /* @__PURE__ */
|
|
3787
|
-
rightPane: /* @__PURE__ */
|
|
3931
|
+
leftPane: /* @__PURE__ */ jsx22(CalendarPane, {}),
|
|
3932
|
+
centerPane: /* @__PURE__ */ jsx22(TasksPane, {}),
|
|
3933
|
+
rightPane: /* @__PURE__ */ jsx22(TimelinePane, {}),
|
|
3788
3934
|
activePane,
|
|
3789
3935
|
height: height - 2
|
|
3790
3936
|
}
|
|
3791
3937
|
),
|
|
3792
|
-
exitConfirmation && /* @__PURE__ */
|
|
3938
|
+
exitConfirmation && /* @__PURE__ */ jsx22(Box17, { width: "100%", justifyContent: "center", paddingY: 1, children: /* @__PURE__ */ jsxs16(Text14, { backgroundColor: "red", color: "white", bold: true, children: [
|
|
3793
3939
|
" ",
|
|
3794
3940
|
"Press Ctrl+C again to exit Epoch",
|
|
3795
3941
|
" "
|
|
@@ -3797,12 +3943,12 @@ var AppContent = () => {
|
|
|
3797
3943
|
] }) });
|
|
3798
3944
|
};
|
|
3799
3945
|
var App = () => {
|
|
3800
|
-
return /* @__PURE__ */
|
|
3946
|
+
return /* @__PURE__ */ jsx22(StorageProvider, { children: /* @__PURE__ */ jsx22(ThemeProvider, { initialTheme: "dark", children: /* @__PURE__ */ jsx22(AppProvider, { children: /* @__PURE__ */ jsx22(AppContent, {}) }) }) });
|
|
3801
3947
|
};
|
|
3802
3948
|
var App_default = App;
|
|
3803
3949
|
|
|
3804
3950
|
// src/index.tsx
|
|
3805
|
-
import { jsx as
|
|
3951
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
3806
3952
|
console.clear();
|
|
3807
|
-
var app = render(/* @__PURE__ */
|
|
3953
|
+
var app = render(/* @__PURE__ */ jsx23(App_default, {}), { exitOnCtrlC: false });
|
|
3808
3954
|
global.__inkApp = app;
|