feat(voice): microphone in the add-task and add-item rows; phone fixes in the column dialog
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m38s
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m38s
VoiceInputButton brings the Quick Dump microphone into other input rows (useVoiceInput, appends to the text already there, hidden when voice input is off or unsupported): the add-task row above the task list and the add-item field of lists (desktop row and phone sheet). Column dialog on phones: the add-column buttons go below the field, and the Erledigt toggle of a column shows only its tick, so the bin stays on screen. Docs and changelog; v0.32.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
08081e6c1d
commit
83b3f27b3e
9 files changed
+168
-44
No files matched your search
@@ -35,6 +35,7 @@ import { api, triggerHaptic } from '../../lib/api';
|
||||
import { UnifiedShareModal } from '../../components/UnifiedShareModal';
|
||||
import { TaskDetailModal } from './TaskDetailModal';
|
||||
import { OriginBadge } from '../../components/OriginBadge';
|
||||
import { VoiceInputButton } from '../../components/VoiceInputButton';
|
||||
import { ManageColumnsModal, DEFAULT_KANBAN_COLUMNS, columnDotClass } from './ManageColumnsModal';
|
||||
import { AvatarStack, AvatarPerson } from '../../components/AvatarStack';
|
||||
import { CountBadge } from '../../components/CountBadge';
|
||||
@@ -138,6 +139,7 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
|
||||
// Quick Task Add state
|
||||
const [quickTitle, setQuickTitle] = useState('');
|
||||
const [quickVoiceError, setQuickVoiceError] = useState<string | null>(null);
|
||||
const [quickDueDate, setQuickDueDate] = useState('');
|
||||
const quickInputRef = useRef<HTMLInputElement | null>(null);
|
||||
const { setGroups, setPrimaryAction } = useMobileActions();
|
||||
@@ -145,6 +147,8 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
// Mobile task creation & filter modal state
|
||||
const [showMobileCreateModal, setShowMobileCreateModal] = useState(false);
|
||||
const [mobileCreateTitle, setMobileCreateTitle] = useState('');
|
||||
const [mobileVoiceError, setMobileVoiceError] = useState<string | null>(null);
|
||||
const mobileCreateInputRef = useRef<HTMLInputElement | null>(null);
|
||||
const [mobileCreateDueDate, setMobileCreateDueDate] = useState('');
|
||||
const [mobileCreatePriority, setMobileCreatePriority] = useState<PriorityLevel>('normal');
|
||||
const [mobileCreateListId, setMobileCreateListId] = useState<string>('');
|
||||
@@ -1679,13 +1683,21 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
value={quickTitle}
|
||||
onChange={(e) => setQuickTitle(e.target.value)}
|
||||
placeholder={
|
||||
currentSelectedList
|
||||
? `Aufgabe zu "${currentSelectedList.title}" hinzufügen…`
|
||||
: 'Neue Aufgabe anlegen…'
|
||||
quickVoiceError ||
|
||||
(currentSelectedList ? `Aufgabe zu "${currentSelectedList.title}" hinzufügen…` : 'Neue Aufgabe anlegen…')
|
||||
}
|
||||
className="flex-1 bg-transparent px-2 py-1.5 sm:py-1 text-sm text-main placeholder-faint focus:outline-none min-w-0"
|
||||
/>
|
||||
<div className="flex items-center gap-1 flex-shrink-0">
|
||||
<VoiceInputButton
|
||||
value={quickTitle}
|
||||
onChange={setQuickTitle}
|
||||
focusRef={quickInputRef}
|
||||
onError={(message) => {
|
||||
setQuickVoiceError(message);
|
||||
window.setTimeout(() => setQuickVoiceError(null), 4000);
|
||||
}}
|
||||
/>
|
||||
<input
|
||||
type="date"
|
||||
value={quickDueDate}
|
||||
@@ -1879,14 +1891,27 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
<form onSubmit={handleMobileCreateTask} className="space-y-3">
|
||||
<div>
|
||||
<label className="text-[11px] font-semibold text-muted block mb-1">Aufgabentext</label>
|
||||
<input
|
||||
type="text"
|
||||
autoFocus
|
||||
value={mobileCreateTitle}
|
||||
onChange={(e) => setMobileCreateTitle(e.target.value)}
|
||||
placeholder="Was ist zu tun?…"
|
||||
className="w-full input-field px-3 py-2 text-sm"
|
||||
/>
|
||||
<div className="relative">
|
||||
<input
|
||||
ref={mobileCreateInputRef}
|
||||
type="text"
|
||||
autoFocus
|
||||
value={mobileCreateTitle}
|
||||
onChange={(e) => setMobileCreateTitle(e.target.value)}
|
||||
placeholder={mobileVoiceError || 'Was ist zu tun?…'}
|
||||
className="w-full input-field pl-3 pr-11 py-2 text-sm"
|
||||
/>
|
||||
<VoiceInputButton
|
||||
value={mobileCreateTitle}
|
||||
onChange={setMobileCreateTitle}
|
||||
focusRef={mobileCreateInputRef}
|
||||
onError={(message) => {
|
||||
setMobileVoiceError(message);
|
||||
window.setTimeout(() => setMobileVoiceError(null), 4000);
|
||||
}}
|
||||
className="absolute right-1 top-1/2 -translate-y-1/2"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* List Selector (if lists exist) */}
|
||||
|
||||
Reference in new issue
Block a user