handle shift key event better

This commit is contained in:
2025-04-19 20:00:14 +00:00
parent f999fe7a80
commit 2c42e95265
3 changed files with 18 additions and 44 deletions

View File

@@ -136,10 +136,10 @@ Please see LICENSE files in the repository root for full details.
} }
.mx_MessageActionBar_deleteButton { .mx_MessageActionBar_deleteButton {
color: var(--cpd-color-red-800); color: var(--cpd-color-red-600);
&:hover { &:hover {
color: var(--cpd-color-red-600); color: var(--cpd-color-red-800);
} }
} }
} }

View File

@@ -425,14 +425,6 @@ export default class MessageActionBar extends React.PureComponent<IMessageAction
PosthogTrackers.trackPinUnpinMessage(isPinned ? "Pin" : "Unpin", "Timeline"); PosthogTrackers.trackPinUnpinMessage(isPinned ? "Pin" : "Unpin", "Timeline");
}; };
private onMouseEnter = (): void => {
this.props.setupShiftKeyListener?.();
};
private onMouseLeave = (): void => {
this.props.removeShiftKeyListener?.();
};
public render(): React.ReactNode { public render(): React.ReactNode {
const isRedacted = this.props.mxEvent.isRedacted(); const isRedacted = this.props.mxEvent.isRedacted();
@@ -637,8 +629,6 @@ export default class MessageActionBar extends React.PureComponent<IMessageAction
className="mx_MessageActionBar" className="mx_MessageActionBar"
aria-label={_t("timeline|mab|label")} aria-label={_t("timeline|mab|label")}
aria-live="off" aria-live="off"
onMouseEnter={this.onMouseEnter}
onMouseLeave={this.onMouseLeave}
> >
{toolbarOpts} {toolbarOpts}
</Toolbar> </Toolbar>

View File

@@ -34,6 +34,7 @@ import {
type UserVerificationStatus, type UserVerificationStatus,
} from "matrix-js-sdk/src/crypto-api"; } from "matrix-js-sdk/src/crypto-api";
import { Tooltip } from "@vector-im/compound-web"; import { Tooltip } from "@vector-im/compound-web";
import { throttle } from "lodash";
import ReplyChain from "../elements/ReplyChain"; import ReplyChain from "../elements/ReplyChain";
import { _t } from "../../../languageHandler"; import { _t } from "../../../languageHandler";
@@ -406,6 +407,10 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
} }
} }
// Add shift key listener
document.addEventListener("keydown", this.checkShiftKey);
document.addEventListener("keyup", this.checkShiftKey);
this.props.mxEvent.on(ThreadEvent.Update, this.updateThread); this.props.mxEvent.on(ThreadEvent.Update, this.updateThread);
client.decryptEventIfNeeded(this.props.mxEvent); client.decryptEventIfNeeded(this.props.mxEvent);
@@ -416,18 +421,6 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
this.verifyEvent(); this.verifyEvent();
} }
private updateThread = (thread: Thread): void => {
this.setState({ thread });
};
public shouldComponentUpdate(nextProps: EventTileProps, nextState: IState): boolean {
if (objectHasDiff(this.state, nextState)) {
return true;
}
return !this.propsEqual(this.props, nextProps);
}
public componentWillUnmount(): void { public componentWillUnmount(): void {
const client = MatrixClientPeg.get(); const client = MatrixClientPeg.get();
if (client) { if (client) {
@@ -445,7 +438,10 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
this.props.mxEvent.off(ThreadEvent.Update, this.updateThread); this.props.mxEvent.off(ThreadEvent.Update, this.updateThread);
this.unmounted = false; this.unmounted = false;
if (this.props.resizeObserver && this.ref.current) this.props.resizeObserver.unobserve(this.ref.current); if (this.props.resizeObserver && this.ref.current) this.props.resizeObserver.unobserve(this.ref.current);
this.removeShiftKeyListener();
// Remove shift key listener
document.removeEventListener("keydown", this.checkShiftKey);
document.removeEventListener("keyup", this.checkShiftKey);
} }
public componentDidUpdate(prevProps: Readonly<EventTileProps>, prevState: Readonly<IState>): void { public componentDidUpdate(prevProps: Readonly<EventTileProps>, prevState: Readonly<IState>): void {
@@ -462,6 +458,10 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
if (this.props.resizeObserver && this.ref.current) this.props.resizeObserver.observe(this.ref.current); if (this.props.resizeObserver && this.ref.current) this.props.resizeObserver.observe(this.ref.current);
} }
private updateThread = (thread: Thread): void => {
this.setState({ thread });
};
private onNewThread = (thread: Thread): void => { private onNewThread = (thread: Thread): void => {
if (thread.id === this.props.mxEvent.getId()) { if (thread.id === this.props.mxEvent.getId()) {
this.updateThread(thread); this.updateThread(thread);
@@ -803,32 +803,16 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
this.setState({ actionBarFocused }); this.setState({ actionBarFocused });
}; };
private checkShiftKey = (): void => { private checkShiftKey = throttle((ev: KeyboardEvent): void => {
if (window.event instanceof MouseEvent) { this.setState({ isShiftHeld: ev.shiftKey });
this.setState({ isShiftHeld: (window.event as unknown as MouseEvent).shiftKey }); }, 200); // Update at most every 200ms
}
};
private setupShiftKeyListener = (): void => {
document.addEventListener("keydown", this.checkShiftKey);
document.addEventListener("keyup", this.checkShiftKey);
this.checkShiftKey();
};
private removeShiftKeyListener = (): void => {
document.removeEventListener("keydown", this.checkShiftKey);
document.removeEventListener("keyup", this.checkShiftKey);
this.setState({ isShiftHeld: false });
};
private onMouseEnter = (): void => { private onMouseEnter = (): void => {
this.setState({ hover: true }); this.setState({ hover: true });
this.setupShiftKeyListener();
}; };
private onMouseLeave = (): void => { private onMouseLeave = (): void => {
this.setState({ hover: false }); this.setState({ hover: false });
this.removeShiftKeyListener();
}; };
private getTile: () => IEventTileType | null = () => this.tile.current; private getTile: () => IEventTileType | null = () => this.tile.current;