Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Start DM on first message
Browse files Browse the repository at this point in the history
Signed-off-by: Michael Weimann <michaelw@matrix.org>
  • Loading branch information
weeman1337 committed May 16, 2022
1 parent 6f85110 commit e5c488a
Show file tree
Hide file tree
Showing 13 changed files with 223 additions and 17 deletions.
1 change: 1 addition & 0 deletions src/PageTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ limitations under the License.
enum PageType {
HomePage = "home_page",
RoomView = "room_view",
LocalRoomView = "local_room_view",
UserView = "user_view",
LegacyGroupView = "legacy_group_view",
}
Expand Down
1 change: 1 addition & 0 deletions src/PosthogTrackers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const notLoggedInMap: Record<Exclude<Views, Views.LOGGED_IN>, ScreenName> = {
const loggedInPageTypeMap: Record<PageType, ScreenName> = {
[PageType.HomePage]: "Home",
[PageType.RoomView]: "Room",
[PageType.LocalRoomView]: "Room",
[PageType.UserView]: "User",
[PageType.LegacyGroupView]: "Group",
};
Expand Down
24 changes: 24 additions & 0 deletions src/components/structures/LoggedInView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import classNames from 'classnames';
import { ISyncStateData, SyncState } from 'matrix-js-sdk/src/sync';
import { IUsageLimit } from 'matrix-js-sdk/src/@types/partials';
import { RoomStateEvent } from "matrix-js-sdk/src/models/room-state";
import { ISendEventResponse } from "matrix-js-sdk/src/@types/requests";
import { IContent } from "matrix-js-sdk/src/models/event";

import { isOnlyCtrlOrCmdKeyEvent, Key } from '../../Keyboard';
import PageTypes from '../../PageTypes';
Expand Down Expand Up @@ -71,6 +73,8 @@ import { SwitchSpacePayload } from "../../dispatcher/payloads/SwitchSpacePayload
import LegacyGroupView from "./LegacyGroupView";
import { IConfigOptions } from "../../IConfigOptions";
import LeftPanelLiveShareWarning from '../views/beacon/LeftPanelLiveShareWarning';
import { startDm } from '../../utils/direct-messages';
import { LocalRoom } from '../../models/LocalRoom';

// We need to fetch each pinned message individually (if we don't already have it)
// so each pinned message may trigger a request. Limit the number per room for sanity.
Expand Down Expand Up @@ -619,8 +623,27 @@ class LoggedInView extends React.Component<IProps, IState> {

render() {
let pageElement;
let messageComposerHandlers;

switch (this.props.page_type) {
case PageTypes.LocalRoomView:
messageComposerHandlers = {
sendMessage: async (
localRoomId: string,
threadId: string | null,
content: IContent,
): Promise<ISendEventResponse> => {
const room = this._matrixClient.store.getRoom(localRoomId);

if (!(room instanceof LocalRoom)) {
return;
}

const rooomId = await startDm(this._matrixClient, room.targets);
return this._matrixClient.sendMessage(rooomId, threadId, content);
},
};
// fallthrough
case PageTypes.RoomView:
pageElement = <RoomView
ref={this._roomView}
Expand All @@ -631,6 +654,7 @@ class LoggedInView extends React.Component<IProps, IState> {
resizeNotifier={this.props.resizeNotifier}
justCreatedOpts={this.props.roomJustCreatedOpts}
forceTimeline={this.props.forceTimeline}
messageComposerHandlers={messageComposerHandlers}
/>;
break;

Expand Down
9 changes: 6 additions & 3 deletions src/components/structures/MatrixChat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -651,12 +651,15 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
case 'view_user_info':
this.viewUser(payload.userId, payload.subAction);
break;
case Action.ViewLocalRoom:
this.viewRoom(payload as ViewRoomPayload, PageType.LocalRoomView);
break;
case Action.ViewRoom: {
// Takes either a room ID or room alias: if switching to a room the client is already
// known to be in (eg. user clicks on a room in the recents panel), supply the ID
// If the user is clicking on a room in the context of the alias being presented
// to them, supply the room alias. If both are supplied, the room ID will be ignored.
const promise = this.viewRoom(payload as ViewRoomPayload);
const promise = this.viewRoom(payload as ViewRoomPayload, PageType.RoomView);
if (payload.deferred_action) {
promise.then(() => {
dis.dispatch(payload.deferred_action);
Expand Down Expand Up @@ -854,7 +857,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
}

// switch view to the given room
private async viewRoom(roomInfo: ViewRoomPayload) {
private async viewRoom(roomInfo: ViewRoomPayload, pageType: PageType) {
this.focusComposer = true;

if (roomInfo.room_alias) {
Expand Down Expand Up @@ -913,7 +916,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
this.setState({
view: Views.LOGGED_IN,
currentRoomId: roomInfo.room_id || null,
page_type: PageType.RoomView,
page_type: pageType,
threepidInvite: roomInfo.threepid_invite,
roomOobData: roomInfo.oob_data,
forceTimeline: roomInfo.forceTimeline,
Expand Down
7 changes: 5 additions & 2 deletions src/components/structures/RoomView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ import SearchResultTile from '../views/rooms/SearchResultTile';
import Spinner from "../views/elements/Spinner";
import UploadBar from './UploadBar';
import RoomStatusBar from "./RoomStatusBar";
import MessageComposer from '../views/rooms/MessageComposer';
import MessageComposer, { IMessageComposerHandlers } from '../views/rooms/MessageComposer';
import JumpToBottomButton from "../views/rooms/JumpToBottomButton";
import TopUnreadMessagesBar from "../views/rooms/TopUnreadMessagesBar";
import { showThread } from '../../dispatcher/dispatch-actions/threads';
Expand Down Expand Up @@ -132,6 +132,8 @@ interface IRoomProps extends MatrixClientProps {

// Called with the credentials of a registered user (if they were a ROU that transitioned to PWLU)
onRegistered?(credentials: IMatrixClientCreds): void;

messageComposerHandlers?: IMessageComposerHandlers;
}

// This defines the content of the mainSplit.
Expand Down Expand Up @@ -2013,6 +2015,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
resizeNotifier={this.props.resizeNotifier}
replyToEvent={this.state.replyToEvent}
permalinkCreator={this.getPermalinkCreatorForRoom(this.state.room)}
handlers={this.props.messageComposerHandlers}
/>;
}

Expand Down Expand Up @@ -2066,7 +2069,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
showReadReceipts={this.state.showReadReceipts}
manageReadReceipts={!this.state.isPeeking}
sendReadReceiptOnLoad={!this.state.wasContextSwitch}
manageReadMarkers={!this.state.isPeeking}
manageReadMarkers={false}
hidden={hideMessagePanel}
highlightedEventId={highlightedEventId}
eventId={this.state.initialEventId}
Expand Down
21 changes: 15 additions & 6 deletions src/components/views/dialogs/InviteDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,13 @@ import CopyableText from "../elements/CopyableText";
import { ScreenName } from '../../../PosthogTrackers';
import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts";
import { getKeyBindingsManager } from "../../../KeyBindingsManager";
import { DirectoryMember, IDMUserTileProps, Member, startDm, ThreepidMember } from "../../../utils/direct-messages";
import {
createDmLocalRoom,
DirectoryMember,
IDMUserTileProps,
Member,
ThreepidMember,
} from "../../../utils/direct-messages";
import { AnyInviteKind, KIND_CALL_TRANSFER, KIND_DM, KIND_INVITE } from './InviteDialogTypes';
import Modal from '../../../Modal';
import dis from "../../../dispatcher/dispatcher";
Expand Down Expand Up @@ -563,20 +569,23 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
}

private startDm = async () => {
this.setState({ busy: true });
try {
const cli = MatrixClientPeg.get();
const targets = this.convertFilter();
await startDm(cli, targets);
const client = MatrixClientPeg.get();
createDmLocalRoom(client, targets);
dis.dispatch({
action: Action.ViewLocalRoom,
room_id: 'local_room',
joining: false,
targets,
});
this.props.onFinished(true);
} catch (err) {
logger.error(err);
this.setState({
busy: false,
errorText: _t("We couldn't create your DM."),
});
} finally {
this.setState({ busy: false });
}
};

Expand Down
12 changes: 12 additions & 0 deletions src/components/views/rooms/MessageComposer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import { RoomMember } from "matrix-js-sdk/src/models/room-member";
import { EventType } from 'matrix-js-sdk/src/@types/event';
import { Optional } from "matrix-events-sdk";
import { THREAD_RELATION_TYPE } from 'matrix-js-sdk/src/models/thread';
import { ISendEventResponse } from 'matrix-js-sdk/src/@types/requests';
import { IContent } from 'matrix-js-sdk/src/models/event';

import { _t } from '../../../languageHandler';
import { MatrixClientPeg } from '../../../MatrixClientPeg';
Expand Down Expand Up @@ -77,6 +79,7 @@ interface IProps {
relation?: IEventRelation;
e2eStatus?: E2EStatus;
compact?: boolean;
handlers?: IMessageComposerHandlers;
}

interface IState {
Expand All @@ -90,6 +93,14 @@ interface IState {
showPollsButton: boolean;
}

export interface IMessageComposerHandlers {
sendMessage: (
roomId: string,
threadId: string | null,
content: IContent,
) => Promise<ISendEventResponse>;
}

export default class MessageComposer extends React.Component<IProps, IState> {
private dispatcherRef: string;
private messageComposerInput = createRef<SendMessageComposerClass>();
Expand Down Expand Up @@ -377,6 +388,7 @@ export default class MessageComposer extends React.Component<IProps, IState> {
onChange={this.onChange}
disabled={this.state.haveRecording}
toggleStickerPickerOpen={this.toggleStickerPickerOpen}
handlers={this.props.handlers}
/>,
);

Expand Down
7 changes: 6 additions & 1 deletion src/components/views/rooms/SendMessageComposer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ import { getSlashCommand, isSlashCommand, runSlashCommand, shouldSendAnyway } fr
import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts";
import { PosthogAnalytics } from "../../../PosthogAnalytics";
import { addReplyToMessageContent } from '../../../utils/Reply';
import { IMessageComposerHandlers } from './MessageComposer';

// Merges favouring the given relation
export function attachRelation(content: IContent, relation?: IEventRelation): void {
Expand Down Expand Up @@ -139,6 +140,7 @@ interface ISendMessageComposerProps extends MatrixClientProps {
onChange?(model: EditorModel): void;
includeReplyLegacyFallback?: boolean;
toggleStickerPickerOpen: () => void;
handlers?: IMessageComposerHandlers;
}

export class SendMessageComposer extends React.Component<ISendMessageComposerProps> {
Expand Down Expand Up @@ -401,7 +403,10 @@ export class SendMessageComposer extends React.Component<ISendMessageComposerPro
? this.props.relation.event_id
: null;

const prom = this.props.mxClient.sendMessage(roomId, threadId, content);
const prom = this.props.handlers
? this.props.handlers.sendMessage(roomId, threadId, content)
: this.props.mxClient.sendMessage(roomId, threadId, content);

if (replyToEvent) {
// Clear reply_to_event as we put the message into the queue
// if the send fails, retry will handle resending.
Expand Down
2 changes: 2 additions & 0 deletions src/dispatcher/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ export enum Action {
*/
ViewRoom = "view_room",

ViewLocalRoom = "view_local_room",

/**
* Changes room based on room list order and payload parameters. Should be used with ViewRoomDeltaPayload.
*/
Expand Down
22 changes: 22 additions & 0 deletions src/dispatcher/payloads/ViewLocalRoomPayload.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
Copyright 2022 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import { Member } from '../../utils/direct-messages';
import { ViewRoomPayload } from './ViewRoomPayload';

export interface ViewLocalRoomPayload extends ViewRoomPayload {
targets: Member[];
}
23 changes: 23 additions & 0 deletions src/models/LocalRoom.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
Copyright 2022 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import { Room } from "matrix-js-sdk/src/models/room";

import { Member } from "../utils/direct-messages";

export class LocalRoom extends Room {
targets: Member[];
}
1 change: 1 addition & 0 deletions src/stores/RoomViewStore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ export class RoomViewStore extends Store<ActionPayload> {
// - event_offset: 100
// - highlighted: true
case Action.ViewRoom:
case Action.ViewLocalRoom:
this.viewRoom(payload);
break;
// for these events blank out the roomId as we are no longer in the RoomView
Expand Down
Loading

0 comments on commit e5c488a

Please sign in to comment.