Skip to content

Commit 7668e34

Browse files
authored
fix: Fix task input editor not allowing submission because empty (#377)
1 parent ad59277 commit 7668e34

File tree

4 files changed

+43
-5
lines changed

4 files changed

+43
-5
lines changed

apps/array/src/renderer/features/message-editor/tiptap/useTiptapEditor.ts

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { toast } from "@renderer/utils/toast";
22
import { useEditor } from "@tiptap/react";
3-
import { useCallback, useRef } from "react";
3+
import { useCallback, useRef, useState } from "react";
44
import type { MentionChip } from "../utils/content";
55
import { contentToXml } from "../utils/content";
66
import { getEditorExtensions } from "./extensions";
@@ -21,6 +21,7 @@ export interface UseTiptapEditorOptions {
2121
onSubmit?: (text: string) => void;
2222
onBashCommand?: (command: string) => void;
2323
onBashModeChange?: (isBashMode: boolean) => void;
24+
onEmptyChange?: (isEmpty: boolean) => void;
2425
}
2526

2627
const EDITOR_CLASS =
@@ -38,6 +39,7 @@ export function useTiptapEditor(options: UseTiptapEditorOptions) {
3839
onSubmit,
3940
onBashCommand,
4041
onBashModeChange,
42+
onEmptyChange,
4143
} = options;
4244

4345
const {
@@ -46,13 +48,27 @@ export function useTiptapEditor(options: UseTiptapEditorOptions) {
4648
bashMode: enableBashMode = true,
4749
} = capabilities;
4850

49-
const callbackRefs = useRef({ onSubmit, onBashCommand, onBashModeChange });
50-
callbackRefs.current = { onSubmit, onBashCommand, onBashModeChange };
51+
const callbackRefs = useRef({
52+
onSubmit,
53+
onBashCommand,
54+
onBashModeChange,
55+
onEmptyChange,
56+
});
57+
callbackRefs.current = {
58+
onSubmit,
59+
onBashCommand,
60+
onBashModeChange,
61+
onEmptyChange,
62+
};
5163

5264
const prevBashModeRef = useRef(false);
65+
const prevIsEmptyRef = useRef(true);
5366
const submitRef = useRef<() => void>(() => {});
5467
const draftRef = useRef<ReturnType<typeof useDraftSync> | null>(null);
5568

69+
// Track isEmpty state to trigger re-renders when content changes
70+
const [isEmptyState, setIsEmptyState] = useState(true);
71+
5672
const handleCommandSubmit = useCallback((text: string) => {
5773
callbackRefs.current.onSubmit?.(text);
5874
}, []);
@@ -86,15 +102,30 @@ export function useTiptapEditor(options: UseTiptapEditorOptions) {
86102
return false;
87103
},
88104
},
105+
onCreate: ({ editor: e }) => {
106+
const newIsEmpty = !e.getText().trim();
107+
setIsEmptyState(newIsEmpty);
108+
prevIsEmptyRef.current = newIsEmpty;
109+
callbackRefs.current.onEmptyChange?.(newIsEmpty);
110+
},
89111
onUpdate: ({ editor: e }) => {
90112
const text = e.getText();
113+
const trimmedText = text.trim();
91114
const newBashMode = enableBashMode && text.trimStart().startsWith("!");
92115

93116
if (newBashMode !== prevBashModeRef.current) {
94117
prevBashModeRef.current = newBashMode;
95118
callbackRefs.current.onBashModeChange?.(newBashMode);
96119
}
97120

121+
const newIsEmpty = !trimmedText;
122+
setIsEmptyState(newIsEmpty);
123+
124+
if (newIsEmpty !== prevIsEmptyRef.current) {
125+
prevIsEmptyRef.current = newIsEmpty;
126+
callbackRefs.current.onEmptyChange?.(newIsEmpty);
127+
}
128+
98129
draftRef.current?.saveDraft(e);
99130
},
100131
},
@@ -159,7 +190,7 @@ export function useTiptapEditor(options: UseTiptapEditorOptions) {
159190
[editor, draft],
160191
);
161192

162-
const isEmpty = !editor || editor.isEmpty;
193+
const isEmpty = !editor || isEmptyState;
163194
const isBashMode =
164195
enableBashMode && (editor?.getText().trimStart().startsWith("!") ?? false);
165196

apps/array/src/renderer/features/task-detail/components/TaskInput.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export function TaskInput() {
4242
const [localWorkspaceMode, setLocalWorkspaceMode] =
4343
useState<LocalWorkspaceMode>(lastUsedLocalWorkspaceMode);
4444
const [selectedBranch, setSelectedBranch] = useState<string | null>(null);
45+
const [editorIsEmpty, setEditorIsEmpty] = useState(true);
4546

4647
const { githubIntegration } = useRepositoryIntegration();
4748

@@ -69,6 +70,7 @@ export function TaskInput() {
6970
githubIntegrationId: githubIntegration?.id,
7071
workspaceMode: effectiveWorkspaceMode,
7172
branch: selectedBranch,
73+
editorIsEmpty,
7274
});
7375

7476
return (
@@ -162,6 +164,7 @@ export function TaskInput() {
162164
hasDirectory={
163165
runMode === "cloud" ? !!selectedRepository : !!selectedDirectory
164166
}
167+
onEmptyChange={setEditorIsEmpty}
165168
/>
166169

167170
<SuggestedTasks editorRef={editorRef} />

apps/array/src/renderer/features/task-detail/components/TaskInputEditor.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ interface TaskInputEditorProps {
2121
canSubmit: boolean;
2222
onSubmit: () => void;
2323
hasDirectory: boolean;
24+
onEmptyChange?: (isEmpty: boolean) => void;
2425
}
2526

2627
export const TaskInputEditor = forwardRef<
@@ -38,6 +39,7 @@ export const TaskInputEditor = forwardRef<
3839
canSubmit,
3940
onSubmit,
4041
hasDirectory,
42+
onEmptyChange,
4143
},
4244
ref,
4345
) => {
@@ -67,6 +69,7 @@ export const TaskInputEditor = forwardRef<
6769
onSubmit();
6870
}
6971
},
72+
onEmptyChange,
7073
});
7174

7275
useImperativeHandle(

apps/array/src/renderer/features/task-detail/hooks/useTaskCreation.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ interface UseTaskCreationOptions {
2424
githubIntegrationId?: number;
2525
workspaceMode: WorkspaceMode;
2626
branch?: string | null;
27+
editorIsEmpty: boolean;
2728
}
2829

2930
interface UseTaskCreationReturn {
@@ -111,6 +112,7 @@ export function useTaskCreation({
111112
githubIntegrationId,
112113
workspaceMode,
113114
branch,
115+
editorIsEmpty,
114116
}: UseTaskCreationOptions): UseTaskCreationReturn {
115117
const [isCreatingTask, setIsCreatingTask] = useState(false);
116118
const { navigateToTask } = useNavigationStore();
@@ -119,7 +121,6 @@ export function useTaskCreation({
119121
const { invalidateTasks } = useCreateTask();
120122

121123
const isCloudMode = workspaceMode === "cloud";
122-
const editorIsEmpty = editorRef.current?.isEmpty() ?? true;
123124
const canSubmit =
124125
!!editorRef.current &&
125126
isAuthenticated &&

0 commit comments

Comments
 (0)