element-web-Github/src/createRoom.js

167 lines
6.2 KiB
JavaScript
Raw Normal View History

/*
Copyright 2015, 2016 OpenMarket Ltd
Copyright 2019, 2020 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.
*/
2019-12-21 05:13:46 +08:00
import {MatrixClientPeg} from './MatrixClientPeg';
import Modal from './Modal';
import * as sdk from './index';
import { _t } from './languageHandler';
import dis from "./dispatcher";
import * as Rooms from "./Rooms";
import DMRoomMap from "./utils/DMRoomMap";
import {getAddressType} from "./UserAddress";
/**
* Create a new room, and switch to it.
*
* @param {object=} opts parameters for creating the room
* @param {string=} opts.dmUserId If specified, make this a DM room for this user and invite them
* @param {object=} opts.createOpts set of options to pass to createRoom call.
* @param {bool=} opts.spinner True to show a modal spinner while the room is created.
* Default: True
* @param {bool=} opts.guestAccess Whether to enable guest access.
* Default: True
*
* @returns {Promise} which resolves to the room id, or null if the
* action was aborted or failed.
*/
export default function createRoom(opts) {
opts = opts || {};
if (opts.spinner === undefined) opts.spinner = true;
if (opts.guestAccess === undefined) opts.guestAccess = true;
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
const Loader = sdk.getComponent("elements.Spinner");
const client = MatrixClientPeg.get();
if (client.isGuest()) {
dis.dispatch({action: 'require_registration'});
return Promise.resolve(null);
}
const defaultPreset = opts.dmUserId ? 'trusted_private_chat' : 'private_chat';
// set some defaults for the creation
const createOpts = opts.createOpts || {};
createOpts.preset = createOpts.preset || defaultPreset;
createOpts.visibility = createOpts.visibility || 'private';
if (opts.dmUserId && createOpts.invite === undefined) {
switch (getAddressType(opts.dmUserId)) {
case 'mx-user-id':
createOpts.invite = [opts.dmUserId];
break;
case 'email':
createOpts.invite_3pid = [{
id_server: MatrixClientPeg.get().getIdentityServerUrl(true),
medium: 'email',
address: opts.dmUserId,
}];
}
}
if (opts.dmUserId && createOpts.is_direct === undefined) {
createOpts.is_direct = true;
}
// By default, view the room after creating it
if (opts.andView === undefined) {
opts.andView = true;
}
// Allow guests by default since the room is private and they'd
// need an invite. This means clicking on a 3pid invite email can
// actually drop you right in to a chat.
createOpts.initial_state = createOpts.initial_state || [];
if (opts.guestAccess) {
createOpts.initial_state.push({
content: {
guest_access: 'can_join',
},
type: 'm.room.guest_access',
state_key: '',
});
}
let modal;
if (opts.spinner) modal = Modal.createDialog(Loader, null, 'mx_Dialog_spinner');
let roomId;
return client.createRoom(createOpts).finally(function() {
if (modal) modal.close();
}).then(function(res) {
roomId = res.room_id;
if (opts.dmUserId) {
return Rooms.setDMRoom(roomId, opts.dmUserId);
} else {
return Promise.resolve();
}
}).then(function() {
// NB createRoom doesn't block on the client seeing the echo that the
// room has been created, so we race here with the client knowing that
// the room exists, causing things like
// https://github.com/vector-im/vector-web/issues/1813
if (opts.andView) {
dis.dispatch({
action: 'view_room',
room_id: roomId,
should_peek: false,
// Creating a room will have joined us to the room,
// so we are expecting the room to come down the sync
// stream, if it hasn't already.
joining: true,
});
}
return roomId;
}, function(err) {
// We also failed to join the room (this sets joining to false in RoomViewStore)
dis.dispatch({
action: 'join_room_error',
});
2017-03-13 06:59:41 +08:00
console.error("Failed to create room " + roomId + " " + err);
let description = _t("Server may be unavailable, overloaded, or you hit a bug.");
if (err.errcode === "M_UNSUPPORTED_ROOM_VERSION") {
// Technically not possible with the UI as of April 2019 because there's no
// options for the user to change this. However, it's not a bad thing to report
// the error to the user for if/when the UI is available.
description = _t("The server does not support the room version specified.");
}
Modal.createTrackedDialog('Failure to create room', '', ErrorDialog, {
title: _t("Failure to create room"),
description,
});
return null;
});
}
export async function ensureDMExists(client, userId) {
const roomIds = DMRoomMap.shared().getDMRoomsForUserId(userId);
const rooms = roomIds.map(id => client.getRoom(id));
const suitableDMRooms = rooms.filter(r => {
if (r && r.getMyMembership() === "join") {
const member = r.getMember(userId);
return member && (member.membership === "invite" || member.membership === "join");
}
return false;
});
let roomId;
if (suitableDMRooms.length) {
const room = suitableDMRooms[0];
roomId = room.roomId;
} else {
roomId = await createRoom({dmUserId: userId, spinner: false, andView: false});
}
return roomId;
}