floq 0.2.3 → 0.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.ja.md +4 -0
- package/README.md +4 -0
- package/dist/i18n/en.d.ts +16 -0
- package/dist/i18n/en.js +9 -0
- package/dist/i18n/ja.js +9 -0
- package/dist/ui/App.js +116 -58
- package/dist/ui/SplashScreen.js +1 -1
- package/dist/ui/components/HelpModal.js +3 -2
- package/dist/ui/components/KanbanBoard.js +100 -40
- package/dist/ui/history/HistoryContext.d.ts +29 -0
- package/dist/ui/history/HistoryContext.js +44 -0
- package/dist/ui/history/HistoryManager.d.ts +56 -0
- package/dist/ui/history/HistoryManager.js +137 -0
- package/dist/ui/history/commands/ConvertToProjectCommand.d.ts +19 -0
- package/dist/ui/history/commands/ConvertToProjectCommand.js +37 -0
- package/dist/ui/history/commands/CreateCommentCommand.d.ts +18 -0
- package/dist/ui/history/commands/CreateCommentCommand.js +23 -0
- package/dist/ui/history/commands/CreateTaskCommand.d.ts +18 -0
- package/dist/ui/history/commands/CreateTaskCommand.js +24 -0
- package/dist/ui/history/commands/DeleteCommentCommand.d.ts +17 -0
- package/dist/ui/history/commands/DeleteCommentCommand.js +26 -0
- package/dist/ui/history/commands/DeleteTaskCommand.d.ts +18 -0
- package/dist/ui/history/commands/DeleteTaskCommand.js +51 -0
- package/dist/ui/history/commands/LinkTaskCommand.d.ts +20 -0
- package/dist/ui/history/commands/LinkTaskCommand.js +37 -0
- package/dist/ui/history/commands/MoveTaskCommand.d.ts +25 -0
- package/dist/ui/history/commands/MoveTaskCommand.js +43 -0
- package/dist/ui/history/commands/index.d.ts +7 -0
- package/dist/ui/history/commands/index.js +7 -0
- package/dist/ui/history/index.d.ts +6 -0
- package/dist/ui/history/index.js +8 -0
- package/dist/ui/history/types.d.ts +26 -0
- package/dist/ui/history/types.js +4 -0
- package/dist/ui/history/useHistory.d.ts +24 -0
- package/dist/ui/history/useHistory.js +31 -0
- package/package.json +1 -1
package/README.ja.md
CHANGED
|
@@ -61,6 +61,8 @@ floq
|
|
|
61
61
|
| `Esc/b` | 戻る |
|
|
62
62
|
| `/` | タスク検索 |
|
|
63
63
|
| `r` | 更新 |
|
|
64
|
+
| `u` | 元に戻す(Undo) |
|
|
65
|
+
| `Ctrl+r` | やり直し(Redo) |
|
|
64
66
|
| `?` | ヘルプ |
|
|
65
67
|
| `q` | 終了 |
|
|
66
68
|
|
|
@@ -107,6 +109,8 @@ floq
|
|
|
107
109
|
| `Enter` | タスク詳細を開く |
|
|
108
110
|
| `/` | タスク検索 |
|
|
109
111
|
| `r` | 更新 |
|
|
112
|
+
| `u` | 元に戻す(Undo) |
|
|
113
|
+
| `Ctrl+r` | やり直し(Redo) |
|
|
110
114
|
| `?` | ヘルプ |
|
|
111
115
|
| `q` | 終了 |
|
|
112
116
|
|
package/README.md
CHANGED
|
@@ -61,6 +61,8 @@ floq
|
|
|
61
61
|
| `Esc/b` | Back |
|
|
62
62
|
| `/` | Search tasks |
|
|
63
63
|
| `r` | Refresh |
|
|
64
|
+
| `u` | Undo |
|
|
65
|
+
| `Ctrl+r` | Redo |
|
|
64
66
|
| `?` | Help |
|
|
65
67
|
| `q` | Quit |
|
|
66
68
|
|
|
@@ -107,6 +109,8 @@ floq
|
|
|
107
109
|
| `Enter` | Open task detail |
|
|
108
110
|
| `/` | Search tasks |
|
|
109
111
|
| `r` | Refresh |
|
|
112
|
+
| `u` | Undo |
|
|
113
|
+
| `Ctrl+r` | Redo |
|
|
110
114
|
| `?` | Help |
|
|
111
115
|
| `q` | Quit |
|
|
112
116
|
|
package/dist/i18n/en.d.ts
CHANGED
|
@@ -136,6 +136,8 @@ export declare const en: {
|
|
|
136
136
|
other: string;
|
|
137
137
|
showHelp: string;
|
|
138
138
|
quit: string;
|
|
139
|
+
undo: string;
|
|
140
|
+
redo: string;
|
|
139
141
|
closeHint: string;
|
|
140
142
|
};
|
|
141
143
|
whatsNew: {
|
|
@@ -181,6 +183,12 @@ export declare const en: {
|
|
|
181
183
|
deleteConfirm: string;
|
|
182
184
|
deleted: string;
|
|
183
185
|
deleteCancelled: string;
|
|
186
|
+
undone: string;
|
|
187
|
+
redone: string;
|
|
188
|
+
nothingToUndo: string;
|
|
189
|
+
nothingToRedo: string;
|
|
190
|
+
undoFailed: string;
|
|
191
|
+
redoFailed: string;
|
|
184
192
|
comments: string;
|
|
185
193
|
projectTasks: string;
|
|
186
194
|
search: {
|
|
@@ -289,6 +297,8 @@ export type HelpTranslations = {
|
|
|
289
297
|
other: string;
|
|
290
298
|
showHelp: string;
|
|
291
299
|
quit: string;
|
|
300
|
+
undo: string;
|
|
301
|
+
redo: string;
|
|
292
302
|
closeHint: string;
|
|
293
303
|
};
|
|
294
304
|
export type WhatsNewTranslations = {
|
|
@@ -407,6 +417,12 @@ export type TuiTranslations = {
|
|
|
407
417
|
deleteConfirm: string;
|
|
408
418
|
deleted: string;
|
|
409
419
|
deleteCancelled: string;
|
|
420
|
+
undone: string;
|
|
421
|
+
redone: string;
|
|
422
|
+
nothingToUndo: string;
|
|
423
|
+
nothingToRedo: string;
|
|
424
|
+
undoFailed: string;
|
|
425
|
+
redoFailed: string;
|
|
410
426
|
comments: string;
|
|
411
427
|
projectTasks: string;
|
|
412
428
|
};
|
package/dist/i18n/en.js
CHANGED
|
@@ -145,6 +145,8 @@ export const en = {
|
|
|
145
145
|
other: 'Other',
|
|
146
146
|
showHelp: 'Show this help',
|
|
147
147
|
quit: 'Quit',
|
|
148
|
+
undo: 'Undo',
|
|
149
|
+
redo: 'Redo',
|
|
148
150
|
closeHint: 'Esc/q: close',
|
|
149
151
|
},
|
|
150
152
|
// What's New / Changelog
|
|
@@ -192,6 +194,13 @@ export const en = {
|
|
|
192
194
|
deleteConfirm: 'Delete "{title}"? (y/n)',
|
|
193
195
|
deleted: 'Deleted: "{title}"',
|
|
194
196
|
deleteCancelled: 'Delete cancelled',
|
|
197
|
+
// Undo/Redo
|
|
198
|
+
undone: 'Undone: {action}',
|
|
199
|
+
redone: 'Redone: {action}',
|
|
200
|
+
nothingToUndo: 'Nothing to undo',
|
|
201
|
+
nothingToRedo: 'Nothing to redo',
|
|
202
|
+
undoFailed: 'Undo failed',
|
|
203
|
+
redoFailed: 'Redo failed',
|
|
195
204
|
comments: 'Comments',
|
|
196
205
|
projectTasks: 'Tasks',
|
|
197
206
|
// Search
|
package/dist/i18n/ja.js
CHANGED
|
@@ -145,6 +145,8 @@ export const ja = {
|
|
|
145
145
|
other: 'その他',
|
|
146
146
|
showHelp: 'このヘルプを表示',
|
|
147
147
|
quit: '終了',
|
|
148
|
+
undo: '元に戻す',
|
|
149
|
+
redo: 'やり直し',
|
|
148
150
|
closeHint: 'Esc/q: 閉じる',
|
|
149
151
|
},
|
|
150
152
|
// What's New / Changelog
|
|
@@ -192,6 +194,13 @@ export const ja = {
|
|
|
192
194
|
deleteConfirm: '「{title}」を削除しますか? (y/n)',
|
|
193
195
|
deleted: '削除しました: 「{title}」',
|
|
194
196
|
deleteCancelled: '削除をキャンセルしました',
|
|
197
|
+
// Undo/Redo
|
|
198
|
+
undone: '元に戻しました: {action}',
|
|
199
|
+
redone: 'やり直しました: {action}',
|
|
200
|
+
nothingToUndo: '元に戻す操作がありません',
|
|
201
|
+
nothingToRedo: 'やり直す操作がありません',
|
|
202
|
+
undoFailed: '元に戻す操作に失敗しました',
|
|
203
|
+
redoFailed: 'やり直しに失敗しました',
|
|
195
204
|
comments: 'コメント',
|
|
196
205
|
projectTasks: 'タスク一覧',
|
|
197
206
|
// Search
|
package/dist/ui/App.js
CHANGED
|
@@ -19,6 +19,7 @@ import { ThemeProvider, useTheme } from './theme/index.js';
|
|
|
19
19
|
import { getThemeName, getViewMode, setThemeName, setViewMode, setLocale, isTursoEnabled } from '../config.js';
|
|
20
20
|
import { KanbanBoard } from './components/KanbanBoard.js';
|
|
21
21
|
import { VERSION } from '../version.js';
|
|
22
|
+
import { HistoryProvider, useHistory, CreateTaskCommand, DeleteTaskCommand, MoveTaskCommand, LinkTaskCommand, ConvertToProjectCommand, CreateCommentCommand, DeleteCommentCommand, } from './history/index.js';
|
|
22
23
|
const TABS = ['inbox', 'next', 'waiting', 'someday', 'projects', 'done'];
|
|
23
24
|
export function App() {
|
|
24
25
|
const [themeName, setThemeNameState] = useState(getThemeName);
|
|
@@ -53,11 +54,12 @@ export function App() {
|
|
|
53
54
|
if (settingsMode === 'lang-select') {
|
|
54
55
|
return (_jsx(ThemeProvider, { themeName: themeName, children: _jsx(LanguageSelector, { onSelect: handleLocaleSelect, onCancel: handleSettingsCancel }) }));
|
|
55
56
|
}
|
|
56
|
-
return (_jsx(ThemeProvider, { themeName: themeName, children: viewMode === 'kanban' ? (_jsx(KanbanBoard, { onOpenSettings: setSettingsMode })) : (_jsx(AppContent, { onOpenSettings: setSettingsMode })) }));
|
|
57
|
+
return (_jsx(ThemeProvider, { themeName: themeName, children: _jsx(HistoryProvider, { children: viewMode === 'kanban' ? (_jsx(KanbanBoard, { onOpenSettings: setSettingsMode })) : (_jsx(AppContent, { onOpenSettings: setSettingsMode })) }) }));
|
|
57
58
|
}
|
|
58
59
|
function AppContent({ onOpenSettings }) {
|
|
59
60
|
const theme = useTheme();
|
|
60
61
|
const { exit } = useApp();
|
|
62
|
+
const history = useHistory();
|
|
61
63
|
const [mode, setMode] = useState('splash');
|
|
62
64
|
const [inputValue, setInputValue] = useState('');
|
|
63
65
|
const [currentListIndex, setCurrentListIndex] = useState(0);
|
|
@@ -189,39 +191,49 @@ function AppContent({ onOpenSettings }) {
|
|
|
189
191
|
const addTask = useCallback(async (title, parentId) => {
|
|
190
192
|
if (!title.trim())
|
|
191
193
|
return;
|
|
192
|
-
const db = getDb();
|
|
193
194
|
const now = new Date();
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
195
|
+
const taskId = uuidv4();
|
|
196
|
+
const command = new CreateTaskCommand({
|
|
197
|
+
task: {
|
|
198
|
+
id: taskId,
|
|
199
|
+
title: title.trim(),
|
|
200
|
+
status: parentId ? 'next' : 'inbox',
|
|
201
|
+
parentId: parentId || null,
|
|
202
|
+
createdAt: now,
|
|
203
|
+
updatedAt: now,
|
|
204
|
+
},
|
|
205
|
+
description: fmt(i18n.tui.added, { title: title.trim() }),
|
|
202
206
|
});
|
|
207
|
+
await history.execute(command);
|
|
203
208
|
setMessage(fmt(i18n.tui.added, { title: title.trim() }));
|
|
204
209
|
await loadTasks();
|
|
205
|
-
}, [i18n.tui.added, loadTasks]);
|
|
210
|
+
}, [i18n.tui.added, loadTasks, history]);
|
|
206
211
|
const addCommentToTask = useCallback(async (task, content) => {
|
|
207
|
-
const
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
212
|
+
const commentId = uuidv4();
|
|
213
|
+
const command = new CreateCommentCommand({
|
|
214
|
+
comment: {
|
|
215
|
+
id: commentId,
|
|
216
|
+
taskId: task.id,
|
|
217
|
+
content: content.trim(),
|
|
218
|
+
createdAt: new Date(),
|
|
219
|
+
},
|
|
220
|
+
description: i18n.tui.commentAdded || 'Comment added',
|
|
213
221
|
});
|
|
222
|
+
await history.execute(command);
|
|
214
223
|
setMessage(i18n.tui.commentAdded || 'Comment added');
|
|
215
224
|
await loadTaskComments(task.id);
|
|
216
|
-
}, [i18n.tui.commentAdded, loadTaskComments]);
|
|
225
|
+
}, [i18n.tui.commentAdded, loadTaskComments, history]);
|
|
217
226
|
const deleteComment = useCallback(async (comment) => {
|
|
218
|
-
const
|
|
219
|
-
|
|
227
|
+
const command = new DeleteCommentCommand({
|
|
228
|
+
comment,
|
|
229
|
+
description: i18n.tui.commentDeleted || 'Comment deleted',
|
|
230
|
+
});
|
|
231
|
+
await history.execute(command);
|
|
220
232
|
setMessage(i18n.tui.commentDeleted || 'Comment deleted');
|
|
221
233
|
if (selectedTask) {
|
|
222
234
|
await loadTaskComments(selectedTask.id);
|
|
223
235
|
}
|
|
224
|
-
}, [i18n.tui.commentDeleted, loadTaskComments, selectedTask]);
|
|
236
|
+
}, [i18n.tui.commentDeleted, loadTaskComments, selectedTask, history]);
|
|
225
237
|
const handleInputSubmit = async (value) => {
|
|
226
238
|
if (mode === 'move-to-waiting' && taskToWaiting) {
|
|
227
239
|
if (value.trim()) {
|
|
@@ -272,54 +284,74 @@ function AppContent({ onOpenSettings }) {
|
|
|
272
284
|
setInputValue('');
|
|
273
285
|
};
|
|
274
286
|
const linkTaskToProject = useCallback(async (task, project) => {
|
|
275
|
-
const
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
.
|
|
287
|
+
const command = new LinkTaskCommand({
|
|
288
|
+
taskId: task.id,
|
|
289
|
+
fromParentId: task.parentId,
|
|
290
|
+
toParentId: project.id,
|
|
291
|
+
description: fmt(i18n.tui.linkedToProject || 'Linked "{title}" to {project}', { title: task.title, project: project.title }),
|
|
292
|
+
});
|
|
293
|
+
await history.execute(command);
|
|
279
294
|
setMessage(fmt(i18n.tui.linkedToProject || 'Linked "{title}" to {project}', { title: task.title, project: project.title }));
|
|
280
295
|
await loadTasks();
|
|
281
|
-
}, [i18n.tui.linkedToProject, loadTasks]);
|
|
296
|
+
}, [i18n.tui.linkedToProject, loadTasks, history]);
|
|
282
297
|
const markTaskDone = useCallback(async (task) => {
|
|
283
|
-
const
|
|
284
|
-
|
|
285
|
-
.
|
|
286
|
-
|
|
298
|
+
const command = new MoveTaskCommand({
|
|
299
|
+
taskId: task.id,
|
|
300
|
+
fromStatus: task.status,
|
|
301
|
+
toStatus: 'done',
|
|
302
|
+
fromWaitingFor: task.waitingFor,
|
|
303
|
+
toWaitingFor: null,
|
|
304
|
+
description: fmt(i18n.tui.completed, { title: task.title }),
|
|
305
|
+
});
|
|
306
|
+
await history.execute(command);
|
|
287
307
|
setMessage(fmt(i18n.tui.completed, { title: task.title }));
|
|
288
308
|
await loadTasks();
|
|
289
|
-
}, [i18n.tui.completed, loadTasks]);
|
|
309
|
+
}, [i18n.tui.completed, loadTasks, history]);
|
|
290
310
|
const moveTaskToStatus = useCallback(async (task, status) => {
|
|
291
|
-
const
|
|
292
|
-
|
|
293
|
-
.
|
|
294
|
-
|
|
311
|
+
const command = new MoveTaskCommand({
|
|
312
|
+
taskId: task.id,
|
|
313
|
+
fromStatus: task.status,
|
|
314
|
+
toStatus: status,
|
|
315
|
+
fromWaitingFor: task.waitingFor,
|
|
316
|
+
toWaitingFor: null,
|
|
317
|
+
description: fmt(i18n.tui.movedTo, { title: task.title, status: i18n.status[status] }),
|
|
318
|
+
});
|
|
319
|
+
await history.execute(command);
|
|
295
320
|
setMessage(fmt(i18n.tui.movedTo, { title: task.title, status: i18n.status[status] }));
|
|
296
321
|
await loadTasks();
|
|
297
|
-
}, [i18n.tui.movedTo, i18n.status, loadTasks]);
|
|
322
|
+
}, [i18n.tui.movedTo, i18n.status, loadTasks, history]);
|
|
298
323
|
const moveTaskToWaiting = useCallback(async (task, waitingFor) => {
|
|
299
|
-
const
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
324
|
+
const command = new MoveTaskCommand({
|
|
325
|
+
taskId: task.id,
|
|
326
|
+
fromStatus: task.status,
|
|
327
|
+
toStatus: 'waiting',
|
|
328
|
+
fromWaitingFor: task.waitingFor,
|
|
329
|
+
toWaitingFor: waitingFor.trim(),
|
|
330
|
+
description: fmt(i18n.tui.movedToWaiting, { title: task.title, person: waitingFor.trim() }),
|
|
331
|
+
});
|
|
332
|
+
await history.execute(command);
|
|
303
333
|
setMessage(fmt(i18n.tui.movedToWaiting, { title: task.title, person: waitingFor.trim() }));
|
|
304
334
|
await loadTasks();
|
|
305
|
-
}, [i18n.tui.movedToWaiting, loadTasks]);
|
|
335
|
+
}, [i18n.tui.movedToWaiting, loadTasks, history]);
|
|
306
336
|
const makeTaskProject = useCallback(async (task) => {
|
|
307
|
-
const
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
337
|
+
const command = new ConvertToProjectCommand({
|
|
338
|
+
taskId: task.id,
|
|
339
|
+
originalStatus: task.status,
|
|
340
|
+
description: fmt(i18n.tui.madeProject || 'Made project: {title}', { title: task.title }),
|
|
341
|
+
});
|
|
342
|
+
await history.execute(command);
|
|
311
343
|
setMessage(fmt(i18n.tui.madeProject || 'Made project: {title}', { title: task.title }));
|
|
312
344
|
await loadTasks();
|
|
313
|
-
}, [i18n.tui.madeProject, loadTasks]);
|
|
345
|
+
}, [i18n.tui.madeProject, loadTasks, history]);
|
|
314
346
|
const deleteTask = useCallback(async (task) => {
|
|
315
|
-
const
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
await
|
|
347
|
+
const command = new DeleteTaskCommand({
|
|
348
|
+
task,
|
|
349
|
+
description: fmt(i18n.tui.deleted || 'Deleted: "{title}"', { title: task.title }),
|
|
350
|
+
});
|
|
351
|
+
await history.execute(command);
|
|
320
352
|
setMessage(fmt(i18n.tui.deleted || 'Deleted: "{title}"', { title: task.title }));
|
|
321
353
|
await loadTasks();
|
|
322
|
-
}, [i18n.tui.deleted, loadTasks]);
|
|
354
|
+
}, [i18n.tui.deleted, loadTasks, history]);
|
|
323
355
|
const getTabLabel = (tab) => {
|
|
324
356
|
switch (tab) {
|
|
325
357
|
case 'inbox':
|
|
@@ -342,10 +374,6 @@ function AppContent({ onOpenSettings }) {
|
|
|
342
374
|
setMode('normal');
|
|
343
375
|
return;
|
|
344
376
|
}
|
|
345
|
-
// Handle help mode - let HelpModal handle input
|
|
346
|
-
if (mode === 'help') {
|
|
347
|
-
return;
|
|
348
|
-
}
|
|
349
377
|
// Handle search mode
|
|
350
378
|
if (mode === 'search') {
|
|
351
379
|
if (key.escape) {
|
|
@@ -760,12 +788,42 @@ function AppContent({ onOpenSettings }) {
|
|
|
760
788
|
return;
|
|
761
789
|
}
|
|
762
790
|
// Refresh
|
|
763
|
-
if (input === 'r') {
|
|
791
|
+
if (input === 'r' && !(key.ctrl)) {
|
|
764
792
|
loadTasks();
|
|
765
793
|
setMessage(i18n.tui.refreshed);
|
|
766
794
|
return;
|
|
767
795
|
}
|
|
768
|
-
|
|
796
|
+
// Undo (u key) - only in normal mode
|
|
797
|
+
if (input === 'u' && mode === 'normal') {
|
|
798
|
+
history.undo().then((didUndo) => {
|
|
799
|
+
if (didUndo) {
|
|
800
|
+
setMessage(fmt(i18n.tui.undone, { action: history.undoDescription || '' }));
|
|
801
|
+
loadTasks();
|
|
802
|
+
}
|
|
803
|
+
else {
|
|
804
|
+
setMessage(i18n.tui.nothingToUndo);
|
|
805
|
+
}
|
|
806
|
+
}).catch(() => {
|
|
807
|
+
setMessage(i18n.tui.undoFailed);
|
|
808
|
+
});
|
|
809
|
+
return;
|
|
810
|
+
}
|
|
811
|
+
// Redo (Ctrl+r) - only in normal mode
|
|
812
|
+
if (key.ctrl && input === 'r' && mode === 'normal') {
|
|
813
|
+
history.redo().then((didRedo) => {
|
|
814
|
+
if (didRedo) {
|
|
815
|
+
setMessage(fmt(i18n.tui.redone, { action: history.redoDescription || '' }));
|
|
816
|
+
loadTasks();
|
|
817
|
+
}
|
|
818
|
+
else {
|
|
819
|
+
setMessage(i18n.tui.nothingToRedo);
|
|
820
|
+
}
|
|
821
|
+
}).catch(() => {
|
|
822
|
+
setMessage(i18n.tui.redoFailed);
|
|
823
|
+
});
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
826
|
+
}, { isActive: mode !== 'help' });
|
|
769
827
|
// Splash screen
|
|
770
828
|
if (mode === 'splash') {
|
|
771
829
|
return _jsx(SplashScreen, { onComplete: () => setMode('normal') });
|
package/dist/ui/SplashScreen.js
CHANGED
|
@@ -57,5 +57,5 @@ export function SplashScreen({ onComplete, duration = 1500 }) {
|
|
|
57
57
|
const visibleLines = Math.min(Math.floor(frame * logoLines.length / 10), logoLines.length);
|
|
58
58
|
return (_jsxs(Box, { flexDirection: "column", alignItems: "center", justifyContent: "center", padding: 2, children: [_jsx(Box, { flexDirection: "column", alignItems: "center", children: logoLines.slice(0, visibleLines).map((line, index) => (_jsx(Text, { color: theme.colors.secondary, bold: true, children: line }, index))) }), showTagline && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: theme.colors.textMuted, italic: !isDosStyle, children: isDosStyle ? `[ ${TAGLINE.toUpperCase()} ]` : TAGLINE }) })), _jsx(Box, { marginTop: 2, children: _jsx(Text, { color: theme.colors.primary, children: frame < 10
|
|
59
59
|
? filled.repeat(frame) + empty.repeat(10 - frame)
|
|
60
|
-
: filled.repeat(10) }) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: theme.colors.textMuted
|
|
60
|
+
: filled.repeat(10) }) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: isDosStyle ? theme.colors.textMuted : theme.colors.muted, children: isDosStyle ? `VER ${VERSION}` : `v${VERSION}` }) })] }));
|
|
61
61
|
}
|
|
@@ -87,6 +87,7 @@ export function HelpModal({ onClose, isKanban = false }) {
|
|
|
87
87
|
// Close modal
|
|
88
88
|
if (key.escape || key.return || input === 'q' || input === ' ') {
|
|
89
89
|
onClose();
|
|
90
|
+
return;
|
|
90
91
|
}
|
|
91
92
|
});
|
|
92
93
|
const formatTitle = (title) => theme.style.headerUppercase ? title.toUpperCase() : title;
|
|
@@ -99,14 +100,14 @@ function GTDKeybindingsContent() {
|
|
|
99
100
|
const help = i18n.tui.help;
|
|
100
101
|
const theme = useTheme();
|
|
101
102
|
const formatTitle = (title) => theme.style.headerUppercase ? title.toUpperCase() : title;
|
|
102
|
-
return (_jsxs(_Fragment, { children: [_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.navigation) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "1-6" }), " ", help.tabSwitch] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "h/l \u2190/\u2192" }), " ", help.prevNextTab] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "j/k \u2191/\u2193" }), " ", help.taskSelect] })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.actions) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "a" }), " ", help.addTask] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "d" }), " ", help.completeTask] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "n" }), " ", help.moveToNext] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "s" }), " ", help.moveToSomeday] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "w" }), " ", help.moveToWaiting] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "i" }), " ", help.moveToInbox] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "r" }), " ", help.refresh] })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.projects) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "p" }), " ", help.makeProject] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "P" }), " ", help.linkToProject] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "Enter" }), " ", help.openProject] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "Esc/b" }), " ", help.backFromProject] })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.settings) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "T" }), " ", help.changeTheme] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "V" }), " ", help.changeViewMode] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "L" }), " ", help.changeLanguage] })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.other) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "/" }), " ", help.searchTasks] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "?" }), " ", help.showHelp] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "q" }), " ", help.quit] })] })] })] }));
|
|
103
|
+
return (_jsxs(_Fragment, { children: [_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.navigation) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "1-6" }), " ", help.tabSwitch] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "h/l \u2190/\u2192" }), " ", help.prevNextTab] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "j/k \u2191/\u2193" }), " ", help.taskSelect] })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.actions) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "a" }), " ", help.addTask] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "d" }), " ", help.completeTask] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "n" }), " ", help.moveToNext] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "s" }), " ", help.moveToSomeday] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "w" }), " ", help.moveToWaiting] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "i" }), " ", help.moveToInbox] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "r" }), " ", help.refresh] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "u" }), " ", help.undo] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "Ctrl+r" }), " ", help.redo] })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.projects) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "p" }), " ", help.makeProject] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "P" }), " ", help.linkToProject] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "Enter" }), " ", help.openProject] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "Esc/b" }), " ", help.backFromProject] })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.settings) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "T" }), " ", help.changeTheme] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "V" }), " ", help.changeViewMode] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "L" }), " ", help.changeLanguage] })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.other) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "/" }), " ", help.searchTasks] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "?" }), " ", help.showHelp] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "q" }), " ", help.quit] })] })] })] }));
|
|
103
104
|
}
|
|
104
105
|
function KanbanKeybindingsContent() {
|
|
105
106
|
const i18n = t();
|
|
106
107
|
const help = i18n.tui.kanbanHelp;
|
|
107
108
|
const theme = useTheme();
|
|
108
109
|
const formatTitle = (title) => theme.style.headerUppercase ? title.toUpperCase() : title;
|
|
109
|
-
return (_jsxs(_Fragment, { children: [_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.navigation) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "h/l \u2190/\u2192" }), " ", help.columnSwitch] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "1-3" }), " ", help.columnDirect] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "j/k \u2191/\u2193" }), " ", help.taskSelect] })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.actions) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "a" }), " ", help.addTask] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "d" }), " ", help.completeTask] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "Enter" }), " ", help.moveRight] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "BS" }), " ", help.moveLeft] })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.settings) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "T" }), " ", help.changeTheme] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "V" }), " ", help.changeViewMode] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "L" }), " ", help.changeLanguage] })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.other) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "/" }), " ", help.searchTasks] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "?" }), " ", help.showHelp] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "q" }), " ", help.quit] })] })] })] }));
|
|
110
|
+
return (_jsxs(_Fragment, { children: [_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.navigation) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "h/l \u2190/\u2192" }), " ", help.columnSwitch] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "1-3" }), " ", help.columnDirect] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "j/k \u2191/\u2193" }), " ", help.taskSelect] })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.actions) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "a" }), " ", help.addTask] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "d" }), " ", help.completeTask] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "Enter" }), " ", help.moveRight] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "BS" }), " ", help.moveLeft] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "u" }), " Undo"] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "Ctrl+r" }), " Redo"] })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.settings) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "T" }), " ", help.changeTheme] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "V" }), " ", help.changeViewMode] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "L" }), " ", help.changeLanguage] })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.other) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "/" }), " ", help.searchTasks] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "?" }), " ", help.showHelp] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "q" }), " ", help.quit] })] })] })] }));
|
|
110
111
|
}
|
|
111
112
|
function InfoContent() {
|
|
112
113
|
const i18n = t();
|