mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 21:15:32 +09:00
fix(threads): keep Tab and focus inside the thread create pane (#3296)
This commit is contained in:
1 parent
663572fd10
commit
b8f3dbddbf
2 files changed
+25
-2
No files matched your search
@@ -1,7 +1,11 @@
|
|||||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
import {Routes} from '@app/app/Routes';
|
import {Routes} from '@app/app/Routes';
|
||||||
import {CHANNEL_TEXTAREA_SELECTOR} from '@app/features/app/keybindings/utils/EditableElement';
|
import {
|
||||||
|
CHANNEL_TEXTAREA_SELECTOR,
|
||||||
|
isChannelTextareaElement,
|
||||||
|
isEditableElement,
|
||||||
|
} from '@app/features/app/keybindings/utils/EditableElement';
|
||||||
import {useLocation} from '@app/features/platform/components/router/RouterReact';
|
import {useLocation} from '@app/features/platform/components/router/RouterReact';
|
||||||
import {ComponentBus} from '@app/features/platform/utils/ComponentBus';
|
import {ComponentBus} from '@app/features/platform/utils/ComponentBus';
|
||||||
import FocusRingManager from '@app/features/ui/focus_ring/FocusRingManager';
|
import FocusRingManager from '@app/features/ui/focus_ring/FocusRingManager';
|
||||||
@@ -29,6 +33,7 @@ const canRedirectTabToComposer = (composer: HTMLTextAreaElement | null): compose
|
|||||||
if (composer == null || composer.disabled || composer.getAttribute('aria-disabled') === 'true') return false;
|
if (composer == null || composer.disabled || composer.getAttribute('aria-disabled') === 'true') return false;
|
||||||
if (isElementInert(composer)) return false;
|
if (isElementInert(composer)) return false;
|
||||||
const active = document.activeElement;
|
const active = document.activeElement;
|
||||||
|
if (isEditableElement(active) && !isChannelTextareaElement(active)) return false;
|
||||||
return !(active instanceof Element && active.closest(FOCUS_TRAPPING_OVERLAY_SELECTOR) != null);
|
return !(active instanceof Element && active.closest(FOCUS_TRAPPING_OVERLAY_SELECTOR) != null);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {CloudUpload} from '@app/features/messaging/upload/CloudUpload';
|
|||||||
import * as MessageSubmitUtils from '@app/features/messaging/utils/MessageSubmitUtils';
|
import * as MessageSubmitUtils from '@app/features/messaging/utils/MessageSubmitUtils';
|
||||||
import {formatUploadingAttachmentSummary} from '@app/features/messaging/utils/UploadingAttachmentLabelUtils';
|
import {formatUploadingAttachmentSummary} from '@app/features/messaging/utils/UploadingAttachmentLabelUtils';
|
||||||
import Permission from '@app/features/permissions/state/Permission';
|
import Permission from '@app/features/permissions/state/Permission';
|
||||||
|
import {shouldDisableAutofocusOnMobile} from '@app/features/platform/utils/AutofocusUtils';
|
||||||
import * as ThreadCommands from '@app/features/threads/commands/ThreadCommands';
|
import * as ThreadCommands from '@app/features/threads/commands/ThreadCommands';
|
||||||
import {openThread} from '@app/features/threads/commands/ThreadNavigation';
|
import {openThread} from '@app/features/threads/commands/ThreadNavigation';
|
||||||
import styles from '@app/features/threads/components/ThreadCreatePane.module.css';
|
import styles from '@app/features/threads/components/ThreadCreatePane.module.css';
|
||||||
@@ -71,6 +72,23 @@ export const ThreadCreatePane = observer(({parent, messageId}: ThreadCreatePaneP
|
|||||||
const [isPrivate, setIsPrivate] = useState(false);
|
const [isPrivate, setIsPrivate] = useState(false);
|
||||||
const nameRef = useRef(name);
|
const nameRef = useRef(name);
|
||||||
nameRef.current = name;
|
nameRef.current = name;
|
||||||
|
const nameInputRef = useRef<HTMLInputElement>(null);
|
||||||
|
useEffect(() => {
|
||||||
|
const input = nameInputRef.current;
|
||||||
|
if (!input || shouldDisableAutofocusOnMobile()) return;
|
||||||
|
const inertRoot = input.closest('[inert]');
|
||||||
|
if (!inertRoot) {
|
||||||
|
input.focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const observer = new MutationObserver(() => {
|
||||||
|
if (input.closest('[inert]')) return;
|
||||||
|
observer.disconnect();
|
||||||
|
input.focus();
|
||||||
|
});
|
||||||
|
observer.observe(inertRoot, {attributes: true, attributeFilter: ['inert']});
|
||||||
|
return () => observer.disconnect();
|
||||||
|
}, []);
|
||||||
const sourceMessage = messageId ? Messages.getMessage(parent.id, messageId) : undefined;
|
const sourceMessage = messageId ? Messages.getMessage(parent.id, messageId) : undefined;
|
||||||
const draftKey = `thread-create:${parent.id}`;
|
const draftKey = `thread-create:${parent.id}`;
|
||||||
const accountKey = Users.viewAccountKey;
|
const accountKey = Users.viewAccountKey;
|
||||||
@@ -138,6 +156,7 @@ export const ThreadCreatePane = observer(({parent, messageId}: ThreadCreatePaneP
|
|||||||
<ChatsIcon className={styles.iconGlyph} data-flx="threads.thread-create-pane.icon-glyph" />
|
<ChatsIcon className={styles.iconGlyph} data-flx="threads.thread-create-pane.icon-glyph" />
|
||||||
</div>
|
</div>
|
||||||
<Input
|
<Input
|
||||||
|
ref={nameInputRef}
|
||||||
value={name}
|
value={name}
|
||||||
onChange={(event) => {
|
onChange={(event) => {
|
||||||
setName(event.target.value);
|
setName(event.target.value);
|
||||||
@@ -146,7 +165,6 @@ export const ThreadCreatePane = observer(({parent, messageId}: ThreadCreatePaneP
|
|||||||
label={i18n._(D.THREAD_NAME_DESCRIPTOR)}
|
label={i18n._(D.THREAD_NAME_DESCRIPTOR)}
|
||||||
placeholder={sourceMessage?.content.slice(0, THREAD_NAME_MAX_LENGTH) || i18n._(D.NEW_THREAD_DESCRIPTOR)}
|
placeholder={sourceMessage?.content.slice(0, THREAD_NAME_MAX_LENGTH) || i18n._(D.NEW_THREAD_DESCRIPTOR)}
|
||||||
maxLength={THREAD_NAME_MAX_LENGTH}
|
maxLength={THREAD_NAME_MAX_LENGTH}
|
||||||
autoFocus
|
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
error={nameError}
|
error={nameError}
|
||||||
data-flx="threads.thread-create-pane.input.name"
|
data-flx="threads.thread-create-pane.input.name"
|
||||||
|
|||||||
Reference in new issue
Block a user