From 17edfa94031fc8803cbe0db28905e52225e664a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Wed, 19 Aug 2026 10:45:30 +0000 Subject: [PATCH] real forms across the plugin, so enter submits instead of doing nothing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit connection settings, add/move/rename/options dialogs and daemon settings all put their fields in a div, so the button was the only way to submit and enter silently did nothing — a keyboard trap wearing a layout. wrapped each in a
, made every non-submit button in those forms type="button" (test port, update blocklist, discard, cancel, remove-file, known-dir shortcuts), and dropped RenameDialog's manual onKeyDown enter check now that the form handles it natively. the toolbar's filter box is left alone — it has no submit action. Co-Authored-By: Claude Opus 5 --- web/ConnectionView.tsx | 12 ++++++----- web/SettingsView.tsx | 22 +++++++++++++------ web/dialogs/AddTorrentDialog.tsx | 27 ++++++++++++----------- web/dialogs/MoveTorrentDialog.tsx | 24 +++++++++++---------- web/dialogs/RenameDialog.tsx | 32 ++++++++++++---------------- web/dialogs/TorrentOptionsDialog.tsx | 24 +++++++++++---------- 6 files changed, 76 insertions(+), 65 deletions(-) diff --git a/web/ConnectionView.tsx b/web/ConnectionView.tsx index c7d2bcd..d40ea99 100644 --- a/web/ConnectionView.tsx +++ b/web/ConnectionView.tsx @@ -1,4 +1,5 @@ import type { ServiceConnection } from 'officerdev'; +import type { FormEvent } from 'react'; import { useEffect, useState } from 'react'; import { CheckCircle2, Loader2, Plug, Trash2, TriangleAlert } from 'lucide-react'; import { Button } from '@/components/ui/button'; @@ -89,7 +90,8 @@ export const ConnectionView = () => { setShowAdvanced(!!connection?.username); }, [connection?.id]); - const submit = async () => { + const submit = async (ev?: FormEvent) => { + ev?.preventDefault(); setError(''); try { await save.mutateAsync({ url: url.trim(), username: username.trim(), password, rpcPath: rpcPath.trim() }); @@ -135,7 +137,7 @@ export const ConnectionView = () => { {connection && } -
+ { )}
- {connection && ( - )}
-
+ ); diff --git a/web/SettingsView.tsx b/web/SettingsView.tsx index 927579a..39962bf 100644 --- a/web/SettingsView.tsx +++ b/web/SettingsView.tsx @@ -1,4 +1,4 @@ -import type { ReactNode } from 'react'; +import type { FormEvent, ReactNode } from 'react'; import { useState } from 'react'; import { Loader2, Plug, ShieldCheck } from 'lucide-react'; import { Button } from '@/components/ui/button'; @@ -45,7 +45,8 @@ export const SettingsView = () => { const dirty = Object.keys(draft).length > 0; - const apply = async () => { + const apply = async (ev?: FormEvent) => { + ev?.preventDefault(); await save.mutateAsync(draft); setDraft({}); }; @@ -80,7 +81,7 @@ export const SettingsView = () => { ); return ( -
+
Downloads @@ -167,7 +168,13 @@ export const SettingsView = () => { {bool('peer-port-random-on-start', 'Pick a random port on each start')} {bool('port-forwarding-enabled', 'Ask the router to forward it (UPnP / NAT-PMP)')}
- -
)} -
+ ); }; diff --git a/web/dialogs/AddTorrentDialog.tsx b/web/dialogs/AddTorrentDialog.tsx index 1f5fe56..53a9e5f 100644 --- a/web/dialogs/AddTorrentDialog.tsx +++ b/web/dialogs/AddTorrentDialog.tsx @@ -1,4 +1,4 @@ -import type { ChangeEvent, DragEvent } from 'react'; +import type { ChangeEvent, DragEvent, FormEvent } from 'react'; import { useState } from 'react'; import { FileUp, Loader2, X } from 'lucide-react'; import { toast } from 'sonner'; @@ -98,7 +98,8 @@ export const AddTorrentDialog = ({ open, onOpenChange }: AddTorrentDialogProps) const canSubmit = (files.length > 0 || urlList.length > 0) && !busy; - const submit = async () => { + const submit = async (ev?: FormEvent) => { + ev?.preventDefault(); const common = { downloadDir: downloadDir.trim() || undefined, labels: labels @@ -148,7 +149,7 @@ export const AddTorrentDialog = ({ open, onOpenChange }: AddTorrentDialogProps) Paste magnet links or drop .torrent files. -
+