Wire up drag-drop file uploads for the thread view (#7860)

This commit is contained in:
Michael Telatynski 2022-02-22 11:14:56 +00:00 committed by GitHub
parent 42e9ea4540
commit 8fccef86d8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 616 additions and 482 deletions

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React, { createRef, KeyboardEvent } from 'react';
import { Thread, ThreadEvent } from 'matrix-js-sdk/src/models/thread';
import { RelationType } from 'matrix-js-sdk/src/@types/event';
import { Room } from 'matrix-js-sdk/src/models/room';
@ -46,6 +46,9 @@ import ThreadListContextMenu from '../views/context_menus/ThreadListContextMenu'
import RightPanelStore from '../../stores/right-panel/RightPanelStore';
import SettingsStore from "../../settings/SettingsStore";
import { ViewRoomPayload } from "../../dispatcher/payloads/ViewRoomPayload";
import FileDropTarget from "./FileDropTarget";
import { getKeyBindingsManager } from "../../KeyBindingsManager";
import { KeyBindingAction } from "../../accessibility/KeyboardShortcuts";
interface IProps {
room: Room;
@ -68,9 +71,11 @@ interface IState {
@replaceableComponent("structures.ThreadView")
export default class ThreadView extends React.Component<IProps, IState> {
static contextType = RoomContext;
public context!: React.ContextType<typeof RoomContext>;
private dispatcherRef: string;
private timelinePanelRef: React.RefObject<TimelinePanel> = React.createRef();
private timelinePanelRef = createRef<TimelinePanel>();
private cardRef = createRef<HTMLDivElement>();
private readonly layoutWatcherRef: string;
constructor(props: IProps) {
@ -206,6 +211,27 @@ export default class ThreadView extends React.Component<IProps, IState> {
}
};
private onKeyDown = (ev: KeyboardEvent) => {
let handled = false;
const action = getKeyBindingsManager().getRoomAction(ev);
switch (action) {
case KeyBindingAction.UploadFile: {
dis.dispatch({
action: "upload_file",
context: TimelineRenderingType.Thread,
}, true);
handled = true;
break;
}
}
if (handled) {
ev.stopPropagation();
ev.preventDefault();
}
};
private renderThreadViewHeader = (): JSX.Element => {
return <div className="mx_ThreadPanel__header">
<span>{ _t("Thread") }</span>
@ -240,18 +266,32 @@ export default class ThreadView extends React.Component<IProps, IState> {
return timelineWindow.paginate(direction, limit);
};
public render(): JSX.Element {
const highlightedEventId = this.props.isInitialEventHighlighted
? this.props.initialEvent?.getId()
: null;
private onFileDrop = (dataTransfer: DataTransfer) => {
ContentMessages.sharedInstance().sendContentListToRoom(
Array.from(dataTransfer.files),
this.props.mxEvent.getRoomId(),
this.threadRelation,
MatrixClientPeg.get(),
TimelineRenderingType.Thread,
);
};
const threadRelation: IEventRelation = {
private get threadRelation(): IEventRelation {
return {
"rel_type": RelationType.Thread,
"event_id": this.state.thread?.id,
"m.in_reply_to": {
"event_id": this.state.lastThreadReply?.getId() ?? this.state.thread?.id,
},
};
}
public render(): JSX.Element {
const highlightedEventId = this.props.isInitialEventHighlighted
? this.props.initialEvent?.getId()
: null;
const threadRelation = this.threadRelation;
const messagePanelClassNames = classNames(
"mx_RoomView_messagePanel",
@ -272,8 +312,11 @@ export default class ThreadView extends React.Component<IProps, IState> {
onClose={this.props.onClose}
withoutScrollContainer={true}
header={this.renderThreadViewHeader()}
ref={this.cardRef}
onKeyDown={this.onKeyDown}
>
{ this.state.thread && (
{ this.state.thread && <div className="mx_ThreadView_timelinePanelWrapper">
<FileDropTarget parent={this.cardRef.current} onFileDrop={this.onFileDrop} />
<TimelinePanel
ref={this.timelinePanelRef}
showReadReceipts={false} // Hide the read receipts
@ -297,7 +340,7 @@ export default class ThreadView extends React.Component<IProps, IState> {
onUserScroll={this.onScroll}
onPaginationRequest={this.onPaginationRequest}
/>
) }
</div> }
{ ContentMessages.sharedInstance().getCurrentUploads(threadRelation).length > 0 && (
<UploadBar room={this.props.room} relation={threadRelation} />