matrix-react-sdk
Version:
SDK for matrix.org using React
981 lines (851 loc) • 119 kB
JavaScript
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.SpaceFeedbackPrompt = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireWildcard(require("react"));
var _event = require("matrix-js-sdk/src/@types/event");
var _MatrixClientContext = _interopRequireDefault(require("../../contexts/MatrixClientContext"));
var _RoomAvatar = _interopRequireDefault(require("../views/avatars/RoomAvatar"));
var _languageHandler = require("../../languageHandler");
var _AccessibleButton = _interopRequireDefault(require("../views/elements/AccessibleButton"));
var _RoomName = _interopRequireDefault(require("../views/elements/RoomName"));
var _RoomTopic = _interopRequireDefault(require("../views/elements/RoomTopic"));
var _InlineSpinner = _interopRequireDefault(require("../views/elements/InlineSpinner"));
var _RoomInvite = require("../../RoomInvite");
var _useRoomMembers = require("../../hooks/useRoomMembers");
var _createRoom = _interopRequireWildcard(require("../../createRoom"));
var _Field = _interopRequireDefault(require("../views/elements/Field"));
var _useEventEmitter = require("../../hooks/useEventEmitter");
var _Validation = _interopRequireDefault(require("../views/elements/Validation"));
var Email = _interopRequireWildcard(require("../../email"));
var _dispatcher = _interopRequireDefault(require("../../dispatcher/dispatcher"));
var _actions = require("../../dispatcher/actions");
var _MainSplit = _interopRequireDefault(require("./MainSplit"));
var _ErrorBoundary = _interopRequireDefault(require("../views/elements/ErrorBoundary"));
var _RightPanel = _interopRequireDefault(require("./RightPanel"));
var _RightPanelStore = _interopRequireDefault(require("../../stores/RightPanelStore"));
var _RightPanelStorePhases = require("../../stores/RightPanelStorePhases");
var _useStateArray = require("../../hooks/useStateArray");
var _SpacePublicShare = _interopRequireDefault(require("../views/spaces/SpacePublicShare"));
var _space = require("../../utils/space");
var _SpaceRoomDirectory = require("./SpaceRoomDirectory");
var _MemberAvatar = _interopRequireDefault(require("../views/avatars/MemberAvatar"));
var _useStateToggle = require("../../hooks/useStateToggle");
var _SpaceStore = _interopRequireDefault(require("../../stores/SpaceStore"));
var _FacePile = _interopRequireDefault(require("../views/elements/FacePile"));
var _AddExistingToSpaceDialog = require("../views/dialogs/AddExistingToSpaceDialog");
var _ContextMenu = require("./ContextMenu");
var _IconizedContextMenu = _interopRequireWildcard(require("../views/context_menus/IconizedContextMenu"));
var _AccessibleTooltipButton = _interopRequireDefault(require("../views/elements/AccessibleTooltipButton"));
var _BetaCard = require("../views/beta/BetaCard");
var _UserSettingsDialog = require("../views/dialogs/UserSettingsDialog");
var _SettingsStore = _interopRequireDefault(require("../../settings/SettingsStore"));
var _Modal = _interopRequireDefault(require("../../Modal"));
var _BetaFeedbackDialog = _interopRequireDefault(require("../views/dialogs/BetaFeedbackDialog"));
var _SdkConfig = _interopRequireDefault(require("../../SdkConfig"));
/*
Copyright 2021 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.
*/
var Phase; // XXX: Temporary for the Spaces Beta only
(function (Phase) {
Phase[Phase["Landing"] = 0] = "Landing";
Phase[Phase["PublicCreateRooms"] = 1] = "PublicCreateRooms";
Phase[Phase["PublicShare"] = 2] = "PublicShare";
Phase[Phase["PrivateScope"] = 3] = "PrivateScope";
Phase[Phase["PrivateInvite"] = 4] = "PrivateInvite";
Phase[Phase["PrivateCreateRooms"] = 5] = "PrivateCreateRooms";
Phase[Phase["PrivateExistingRooms"] = 6] = "PrivateExistingRooms";
})(Phase || (Phase = {}));
const SpaceFeedbackPrompt = ({
onClick
}
/*: { onClick?: () => void }*/
) => {
if (!_SdkConfig.default.get().bug_report_endpoint_url) return null;
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceFeedbackPrompt"
}, /*#__PURE__*/_react.default.createElement("hr", null), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("span", {
className: "mx_SpaceFeedbackPrompt_text"
}, (0, _languageHandler._t)("Spaces are a beta feature.")), /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
kind: "link",
onClick: () => {
if (onClick) onClick();
_Modal.default.createTrackedDialog("Beta Feedback", "feature_spaces", _BetaFeedbackDialog.default, {
featureId: "feature_spaces"
});
}
}, (0, _languageHandler._t)("Feedback"))));
};
exports.SpaceFeedbackPrompt = SpaceFeedbackPrompt;
const RoomMemberCount = ({
room,
children
}) => {
const members = (0, _useRoomMembers.useRoomMembers)(room);
const count = members.length;
if (children) return children(count);
return count;
};
const useMyRoomMembership = (room
/*: Room*/
) => {
const [membership, setMembership] = (0, _react.useState)(room.getMyMembership());
(0, _useEventEmitter.useEventEmitter)(room, "Room.myMembership", () => {
setMembership(room.getMyMembership());
});
return membership;
};
const SpaceInfo = ({
space
}) => {
const joinRule = space.getJoinRule();
let visibilitySection;
if (joinRule === "public") {
visibilitySection = /*#__PURE__*/_react.default.createElement("span", {
className: "mx_SpaceRoomView_info_public"
}, (0, _languageHandler._t)("Public space"));
} else {
visibilitySection = /*#__PURE__*/_react.default.createElement("span", {
className: "mx_SpaceRoomView_info_private"
}, (0, _languageHandler._t)("Private space"));
}
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_info"
}, visibilitySection, joinRule === "public" && /*#__PURE__*/_react.default.createElement(RoomMemberCount, {
room: space
}, count => count > 0 ? /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
kind: "link",
onClick: () => {
_dispatcher.default.dispatch({
action: _actions.Action.SetRightPanelPhase,
phase: _RightPanelStorePhases.RightPanelPhases.RoomMemberList,
refireParams: {
space
}
});
}
}, (0, _languageHandler._t)("%(count)s members", {
count
})) : null));
};
const onBetaClick = () => {
_dispatcher.default.dispatch({
action: _actions.Action.ViewUserSettings,
initialTabId: _UserSettingsDialog.USER_LABS_TAB
});
};
const SpacePreview = ({
space,
onJoinButtonClicked,
onRejectButtonClicked
}) => {
const cli = (0, _react.useContext)(_MatrixClientContext.default);
const myMembership = useMyRoomMembership(space);
const [busy, setBusy] = (0, _react.useState)(false);
const spacesEnabled = _SettingsStore.default.getValue("feature_spaces");
let inviterSection;
let joinButtons;
if (myMembership === "join") {
// XXX remove this when spaces leaves Beta
joinButtons = /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
kind: "danger_outline",
onClick: () => {
_dispatcher.default.dispatch({
action: "leave_room",
room_id: space.roomId
});
}
}, (0, _languageHandler._t)("Leave"));
} else if (myMembership === "invite") {
const inviteSender = space.getMember(cli.getUserId())?.events.member?.getSender();
const inviter = inviteSender && space.getMember(inviteSender);
if (inviteSender) {
inviterSection = /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_preview_inviter"
}, /*#__PURE__*/_react.default.createElement(_MemberAvatar.default, {
member: inviter,
width: 32,
height: 32
}), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_preview_inviter_name"
}, (0, _languageHandler._t)("<inviter/> invites you", {}, {
inviter: () => /*#__PURE__*/_react.default.createElement("b", null, inviter.name || inviteSender)
})), inviter ? /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_preview_inviter_mxid"
}, inviteSender) : null));
}
joinButtons = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
kind: "secondary",
onClick: () => {
setBusy(true);
onRejectButtonClicked();
}
}, (0, _languageHandler._t)("Reject")), /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
kind: "primary",
onClick: () => {
setBusy(true);
onJoinButtonClicked();
},
disabled: !spacesEnabled
}, (0, _languageHandler._t)("Accept")));
} else {
joinButtons = /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
kind: "primary",
onClick: () => {
setBusy(true);
onJoinButtonClicked();
},
disabled: !spacesEnabled
}, (0, _languageHandler._t)("Join"));
}
if (busy) {
joinButtons = /*#__PURE__*/_react.default.createElement(_InlineSpinner.default, null);
}
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_preview"
}, /*#__PURE__*/_react.default.createElement(_BetaCard.BetaPill, {
onClick: onBetaClick
}), inviterSection, /*#__PURE__*/_react.default.createElement(_RoomAvatar.default, {
room: space,
height: 80,
width: 80,
viewAvatarOnClick: true
}), /*#__PURE__*/_react.default.createElement("h1", {
className: "mx_SpaceRoomView_preview_name"
}, /*#__PURE__*/_react.default.createElement(_RoomName.default, {
room: space
})), /*#__PURE__*/_react.default.createElement(SpaceInfo, {
space: space
}), /*#__PURE__*/_react.default.createElement(_RoomTopic.default, {
room: space
}, (topic, ref) => /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_preview_topic",
ref: ref
}, topic)), space.getJoinRule() === "public" && /*#__PURE__*/_react.default.createElement(_FacePile.default, {
room: space
}), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_preview_joinButtons"
}, joinButtons), !spacesEnabled && /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_preview_spaceBetaPrompt"
}, myMembership === "join" ? (0, _languageHandler._t)("To view %(spaceName)s, turn on the <a>Spaces beta</a>", {
spaceName: space.name
}, {
a: sub => /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
onClick: onBetaClick,
kind: "link"
}, sub)
}) : (0, _languageHandler._t)("To join %(spaceName)s, turn on the <a>Spaces beta</a>", {
spaceName: space.name
}, {
a: sub => /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
onClick: onBetaClick,
kind: "link"
}, sub)
})));
};
const SpaceLandingAddButton = ({
space,
onNewRoomAdded
}) => {
const cli = (0, _react.useContext)(_MatrixClientContext.default);
const [menuDisplayed, handle, openMenu, closeMenu] = (0, _ContextMenu.useContextMenu)();
let contextMenu;
if (menuDisplayed) {
const rect = handle.current.getBoundingClientRect();
contextMenu = /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.default, {
left: rect.left + window.pageXOffset + 0,
top: rect.bottom + window.pageYOffset + 8,
chevronFace: _ContextMenu.ChevronFace.None,
onFinished: closeMenu,
className: "mx_RoomTile_contextMenu",
compact: true
}, /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.IconizedContextMenuOptionList, {
first: true
}, /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.IconizedContextMenuOption, {
label: (0, _languageHandler._t)("Create new room"),
iconClassName: "mx_RoomList_iconPlus",
onClick: async e => {
e.preventDefault();
e.stopPropagation();
closeMenu();
if (await (0, _space.showCreateNewRoom)(cli, space)) {
onNewRoomAdded();
}
}
}), /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.IconizedContextMenuOption, {
label: (0, _languageHandler._t)("Add existing room"),
iconClassName: "mx_RoomList_iconHash",
onClick: async e => {
e.preventDefault();
e.stopPropagation();
closeMenu();
const [added] = await (0, _space.showAddExistingRooms)(cli, space);
if (added) {
onNewRoomAdded();
}
}
})));
}
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_ContextMenu.ContextMenuButton, {
kind: "primary",
inputRef: handle,
onClick: openMenu,
isExpanded: menuDisplayed,
label: (0, _languageHandler._t)("Add")
}, (0, _languageHandler._t)("Add")), contextMenu);
};
const SpaceLanding = ({
space
}) => {
const cli = (0, _react.useContext)(_MatrixClientContext.default);
const myMembership = useMyRoomMembership(space);
const userId = cli.getUserId();
let inviteButton;
if (myMembership === "join" && space.canInvite(userId)) {
inviteButton = /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
kind: "primary",
className: "mx_SpaceRoomView_landing_inviteButton",
onClick: () => {
(0, _RoomInvite.showRoomInviteDialog)(space.roomId);
}
}, (0, _languageHandler._t)("Invite"));
}
const canAddRooms = myMembership === "join" && space.currentState.maySendStateEvent(_event.EventType.SpaceChild, userId);
const [refreshToken, forceUpdate] = (0, _useStateToggle.useStateToggle)(false);
let addRoomButton;
if (canAddRooms) {
addRoomButton = /*#__PURE__*/_react.default.createElement(SpaceLandingAddButton, {
space: space,
onNewRoomAdded: forceUpdate
});
}
let settingsButton;
if ((0, _space.shouldShowSpaceSettings)(cli, space)) {
settingsButton = /*#__PURE__*/_react.default.createElement(_AccessibleTooltipButton.default, {
className: "mx_SpaceRoomView_landing_settingsButton",
onClick: () => {
(0, _space.showSpaceSettings)(cli, space);
},
title: (0, _languageHandler._t)("Settings")
});
}
const onMembersClick = () => {
_dispatcher.default.dispatch({
action: _actions.Action.SetRightPanelPhase,
phase: _RightPanelStorePhases.RightPanelPhases.RoomMemberList,
refireParams: {
space
}
});
};
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_landing"
}, /*#__PURE__*/_react.default.createElement(_RoomAvatar.default, {
room: space,
height: 80,
width: 80,
viewAvatarOnClick: true
}), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_landing_name"
}, /*#__PURE__*/_react.default.createElement(_RoomName.default, {
room: space
}, name => {
const tags = {
name: () => /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_landing_nameRow"
}, /*#__PURE__*/_react.default.createElement("h1", null, name))
};
return (0, _languageHandler._t)("Welcome to <name/>", {}, tags);
})), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_landing_info"
}, /*#__PURE__*/_react.default.createElement(SpaceInfo, {
space: space
}), /*#__PURE__*/_react.default.createElement(_FacePile.default, {
room: space,
onlyKnownUsers: false,
numShown: 7,
onClick: onMembersClick
}), inviteButton, settingsButton), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_landing_topic"
}, /*#__PURE__*/_react.default.createElement(_RoomTopic.default, {
room: space
})), /*#__PURE__*/_react.default.createElement(SpaceFeedbackPrompt, null), /*#__PURE__*/_react.default.createElement("hr", null), /*#__PURE__*/_react.default.createElement(_SpaceRoomDirectory.SpaceHierarchy, {
space: space,
showRoom: _SpaceRoomDirectory.showRoom,
refreshToken: refreshToken,
additionalButtons: addRoomButton
}));
};
const SpaceSetupFirstRooms = ({
space,
title,
description,
onFinished
}) => {
const [busy, setBusy] = (0, _react.useState)(false);
const [error, setError] = (0, _react.useState)("");
const numFields = 3;
const placeholders = [(0, _languageHandler._t)("General"), (0, _languageHandler._t)("Random"), (0, _languageHandler._t)("Support")]; // TODO vary default prefills for "Just Me" spaces
const [roomNames, setRoomName] = (0, _useStateArray.useStateArray)(numFields, [(0, _languageHandler._t)("General"), (0, _languageHandler._t)("Random"), ""]);
const fields = new Array(numFields).fill(0).map((_, i) => {
const name = "roomName" + i;
return /*#__PURE__*/_react.default.createElement(_Field.default, {
key: name,
name: name,
type: "text",
label: (0, _languageHandler._t)("Room name"),
placeholder: placeholders[i],
value: roomNames[i],
onChange: ev => setRoomName(i, ev.target.value),
autoFocus: i === 2,
disabled: busy
});
});
const onNextClick = async ev => {
ev.preventDefault();
if (busy) return;
setError("");
setBusy(true);
try {
const filteredRoomNames = roomNames.map(name => name.trim()).filter(Boolean);
await Promise.all(filteredRoomNames.map(name => {
return (0, _createRoom.default)({
createOpts: {
preset: space.getJoinRule() === "public" ? _createRoom.Preset.PublicChat : _createRoom.Preset.PrivateChat,
name
},
spinner: false,
encryption: false,
andView: false,
inlineErrors: true,
parentSpace: space
});
}));
onFinished(filteredRoomNames.length > 0);
} catch (e) {
console.error("Failed to create initial space rooms", e);
setError((0, _languageHandler._t)("Failed to create initial space rooms"));
}
setBusy(false);
};
let onClick = ev => {
ev.preventDefault();
onFinished(false);
};
let buttonLabel = (0, _languageHandler._t)("Skip for now");
if (roomNames.some(name => name.trim())) {
onClick = onNextClick;
buttonLabel = busy ? (0, _languageHandler._t)("Creating rooms...") : (0, _languageHandler._t)("Continue");
}
return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("h1", null, title), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_description"
}, description), error && /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_errorText"
}, error), /*#__PURE__*/_react.default.createElement("form", {
onSubmit: onClick,
id: "mx_SpaceSetupFirstRooms"
}, fields), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_buttons"
}, /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
kind: "primary",
disabled: busy,
onClick: onClick,
element: "input",
type: "submit",
form: "mx_SpaceSetupFirstRooms",
value: buttonLabel
})), /*#__PURE__*/_react.default.createElement(SpaceFeedbackPrompt, null));
};
const SpaceAddExistingRooms = ({
space,
onFinished
}) => {
return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("h1", null, (0, _languageHandler._t)("What do you want to organise?")), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_description"
}, (0, _languageHandler._t)("Pick rooms or conversations to add. This is just a space for you, " + "no one will be informed. You can add more later.")), /*#__PURE__*/_react.default.createElement(_AddExistingToSpaceDialog.AddExistingToSpace, {
space: space,
emptySelectionButton: /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
kind: "primary",
onClick: onFinished
}, (0, _languageHandler._t)("Skip for now")),
onFinished: onFinished
}), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_buttons"
}), /*#__PURE__*/_react.default.createElement(SpaceFeedbackPrompt, null));
};
const SpaceSetupPublicShare = ({
justCreatedOpts,
space,
onFinished,
createdRooms
}) => {
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_publicShare"
}, /*#__PURE__*/_react.default.createElement("h1", null, (0, _languageHandler._t)("Share %(name)s", {
name: justCreatedOpts?.createOpts?.name || space.name
})), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_description"
}, (0, _languageHandler._t)("It's just you at the moment, it will be even better with others.")), /*#__PURE__*/_react.default.createElement(_SpacePublicShare.default, {
space: space
}), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_buttons"
}, /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
kind: "primary",
onClick: onFinished
}, createdRooms ? (0, _languageHandler._t)("Go to my first room") : (0, _languageHandler._t)("Go to my space"))), /*#__PURE__*/_react.default.createElement(SpaceFeedbackPrompt, null));
};
const SpaceSetupPrivateScope = ({
space,
justCreatedOpts,
onFinished
}) => {
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_privateScope"
}, /*#__PURE__*/_react.default.createElement("h1", null, (0, _languageHandler._t)("Who are you working with?")), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_description"
}, (0, _languageHandler._t)("Make sure the right people have access to %(name)s", {
name: justCreatedOpts?.createOpts?.name || space.name
})), /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
className: "mx_SpaceRoomView_privateScope_justMeButton",
onClick: () => {
onFinished(false);
}
}, /*#__PURE__*/_react.default.createElement("h3", null, (0, _languageHandler._t)("Just me")), /*#__PURE__*/_react.default.createElement("div", null, (0, _languageHandler._t)("A private space to organise your rooms"))), /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
className: "mx_SpaceRoomView_privateScope_meAndMyTeammatesButton",
onClick: () => {
onFinished(true);
}
}, /*#__PURE__*/_react.default.createElement("h3", null, (0, _languageHandler._t)("Me and my teammates")), /*#__PURE__*/_react.default.createElement("div", null, (0, _languageHandler._t)("A private space for you and your teammates"))), /*#__PURE__*/_react.default.createElement(SpaceFeedbackPrompt, null));
};
const validateEmailRules = (0, _Validation.default)({
rules: [{
key: "email",
test: ({
value
}) => !value || Email.looksValid(value),
invalid: () => (0, _languageHandler._t)("Doesn't look like a valid email address")
}]
});
const SpaceSetupPrivateInvite = ({
space,
onFinished
}) => {
const [busy, setBusy] = (0, _react.useState)(false);
const [error, setError] = (0, _react.useState)("");
const numFields = 3;
const fieldRefs
/*: RefObject<Field>[]*/
= [(0, _react.useRef)(), (0, _react.useRef)(), (0, _react.useRef)()];
const [emailAddresses, setEmailAddress] = (0, _useStateArray.useStateArray)(numFields, "");
const fields = new Array(numFields).fill(0).map((_, i) => {
const name = "emailAddress" + i;
return /*#__PURE__*/_react.default.createElement(_Field.default, {
key: name,
name: name,
type: "text",
label: (0, _languageHandler._t)("Email address"),
placeholder: (0, _languageHandler._t)("Email"),
value: emailAddresses[i],
onChange: ev => setEmailAddress(i, ev.target.value),
ref: fieldRefs[i],
onValidate: validateEmailRules,
autoFocus: i === 0,
disabled: busy
});
});
const onNextClick = async ev => {
ev.preventDefault();
if (busy) return;
setError("");
for (let i = 0; i < fieldRefs.length; i++) {
const fieldRef = fieldRefs[i];
const valid = await fieldRef.current.validate({
allowEmpty: true
});
if (valid === false) {
// true/null are allowed
fieldRef.current.focus();
fieldRef.current.validate({
allowEmpty: true,
focused: true
});
return;
}
}
setBusy(true);
const targetIds = emailAddresses.map(name => name.trim()).filter(Boolean);
try {
const result = await (0, _RoomInvite.inviteMultipleToRoom)(space.roomId, targetIds);
const failedUsers = Object.keys(result.states).filter(a => result.states[a] === "error");
if (failedUsers.length > 0) {
console.log("Failed to invite users to space: ", result);
setError((0, _languageHandler._t)("Failed to invite the following users to your space: %(csvUsers)s", {
csvUsers: failedUsers.join(", ")
}));
} else {
onFinished();
}
} catch (err) {
console.error("Failed to invite users to space: ", err);
setError((0, _languageHandler._t)("We couldn't invite those users. Please check the users you want to invite and try again."));
}
setBusy(false);
};
let onClick = ev => {
ev.preventDefault();
onFinished();
};
let buttonLabel = (0, _languageHandler._t)("Skip for now");
if (emailAddresses.some(name => name.trim())) {
onClick = onNextClick;
buttonLabel = busy ? (0, _languageHandler._t)("Inviting...") : (0, _languageHandler._t)("Continue");
}
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_inviteTeammates"
}, /*#__PURE__*/_react.default.createElement("h1", null, (0, _languageHandler._t)("Invite your teammates")), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_description"
}, (0, _languageHandler._t)("Make sure the right people have access. You can invite more later.")), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_inviteTeammates_betaDisclaimer"
}, /*#__PURE__*/_react.default.createElement(_BetaCard.BetaPill, {
onClick: onBetaClick
}), (0, _languageHandler._t)("<b>This is an experimental feature.</b> For now, " + "new users receiving an invite will have to open the invite on <link/> to actually join.", {}, {
b: sub => /*#__PURE__*/_react.default.createElement("b", null, sub),
link: () => /*#__PURE__*/_react.default.createElement("a", {
href: "https://app.element.io/",
rel: "noreferrer noopener",
target: "_blank"
}, "app.element.io")
})), error && /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_errorText"
}, error), /*#__PURE__*/_react.default.createElement("form", {
onSubmit: onClick,
id: "mx_SpaceSetupPrivateInvite"
}, fields), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_inviteTeammates_buttons"
}, /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
className: "mx_SpaceRoomView_inviteTeammates_inviteDialogButton",
onClick: () => (0, _RoomInvite.showRoomInviteDialog)(space.roomId)
}, (0, _languageHandler._t)("Invite by username"))), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpaceRoomView_buttons"
}, /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
kind: "primary",
disabled: busy,
onClick: onClick,
element: "input",
type: "submit",
form: "mx_SpaceSetupPrivateInvite",
value: buttonLabel
})), /*#__PURE__*/_react.default.createElement(SpaceFeedbackPrompt, null));
};
class SpaceRoomView extends _react.default.PureComponent
/*:: <IProps, IState>*/
{
constructor(props, context) {
super(props, context);
(0, _defineProperty2.default)(this, "creator", void 0);
(0, _defineProperty2.default)(this, "dispatcherRef", void 0);
(0, _defineProperty2.default)(this, "rightPanelStoreToken", void 0);
(0, _defineProperty2.default)(this, "onMyMembership", (room
/*: Room*/
, myMembership
/*: string*/
) => {
if (room.roomId === this.props.space.roomId) {
this.setState({
myMembership
});
}
});
(0, _defineProperty2.default)(this, "onRightPanelStoreUpdate", () => {
this.setState({
showRightPanel: _RightPanelStore.default.getSharedInstance().isOpenForRoom
});
});
(0, _defineProperty2.default)(this, "onAction", (payload
/*: ActionPayload*/
) => {
if (payload.action !== _actions.Action.ViewUser && payload.action !== "view_3pid_invite") return;
if (payload.action === _actions.Action.ViewUser && payload.member) {
_dispatcher.default.dispatch({
action: _actions.Action.SetRightPanelPhase,
phase: _RightPanelStorePhases.RightPanelPhases.SpaceMemberInfo,
refireParams: {
space: this.props.space,
member: payload.member
}
});
} else if (payload.action === "view_3pid_invite" && payload.event) {
_dispatcher.default.dispatch({
action: _actions.Action.SetRightPanelPhase,
phase: _RightPanelStorePhases.RightPanelPhases.Space3pidMemberInfo,
refireParams: {
space: this.props.space,
event: payload.event
}
});
} else {
_dispatcher.default.dispatch({
action: _actions.Action.SetRightPanelPhase,
phase: _RightPanelStorePhases.RightPanelPhases.SpaceMemberList,
refireParams: {
space: this.props.space
}
});
}
});
(0, _defineProperty2.default)(this, "goToFirstRoom", async () => {
// TODO actually go to the first room
const childRooms = _SpaceStore.default.instance.getChildRooms(this.props.space.roomId);
if (childRooms.length) {
const room = childRooms[0];
_dispatcher.default.dispatch({
action: "view_room",
room_id: room.roomId
});
return;
}
let suggestedRooms = _SpaceStore.default.instance.suggestedRooms;
if (_SpaceStore.default.instance.activeSpace !== this.props.space) {
// the space store has the suggested rooms loaded for a different space, fetch the right ones
suggestedRooms = (await _SpaceStore.default.instance.fetchSuggestedRooms(this.props.space, 1)).rooms;
}
if (suggestedRooms.length) {
const room = suggestedRooms[0];
_dispatcher.default.dispatch({
action: "view_room",
room_id: room.room_id,
oobData: {
avatarUrl: room.avatar_url,
name: room.name || room.canonical_alias || room.aliases.pop() || (0, _languageHandler._t)("Empty room")
}
});
return;
}
this.setState({
phase: Phase.Landing
});
});
let phase = Phase.Landing;
this.creator = this.props.space.currentState.getStateEvents(_event.EventType.RoomCreate, "")?.getSender();
const showSetup = this.props.justCreatedOpts && this.context.getUserId() === this.creator;
if (showSetup) {
phase = this.props.justCreatedOpts.createOpts.preset === _createRoom.Preset.PublicChat ? Phase.PublicCreateRooms : Phase.PrivateScope;
}
this.state = {
phase,
showRightPanel: _RightPanelStore.default.getSharedInstance().isOpenForRoom,
myMembership: this.props.space.getMyMembership()
};
this.dispatcherRef = _dispatcher.default.register(this.onAction);
this.rightPanelStoreToken = _RightPanelStore.default.getSharedInstance().addListener(this.onRightPanelStoreUpdate);
this.context.on("Room.myMembership", this.onMyMembership);
}
componentWillUnmount() {
_dispatcher.default.unregister(this.dispatcherRef);
this.rightPanelStoreToken.remove();
this.context.off("Room.myMembership", this.onMyMembership);
}
renderBody() {
switch (this.state.phase) {
case Phase.Landing:
if (this.state.myMembership === "join" && _SettingsStore.default.getValue("feature_spaces")) {
return /*#__PURE__*/_react.default.createElement(SpaceLanding, {
space: this.props.space
});
} else {
return /*#__PURE__*/_react.default.createElement(SpacePreview, {
space: this.props.space,
onJoinButtonClicked: this.props.onJoinButtonClicked,
onRejectButtonClicked: this.props.onRejectButtonClicked
});
}
case Phase.PublicCreateRooms:
return /*#__PURE__*/_react.default.createElement(SpaceSetupFirstRooms, {
space: this.props.space,
title: (0, _languageHandler._t)("What are some things you want to discuss in %(spaceName)s?", {
spaceName: this.props.justCreatedOpts?.createOpts?.name || this.props.space.name
}),
description: (0, _languageHandler._t)("Let's create a room for each of them.") + "\n" + (0, _languageHandler._t)("You can add more later too, including already existing ones."),
onFinished: (createdRooms
/*: boolean*/
) => this.setState({
phase: Phase.PublicShare,
createdRooms
})
});
case Phase.PublicShare:
return /*#__PURE__*/_react.default.createElement(SpaceSetupPublicShare, {
justCreatedOpts: this.props.justCreatedOpts,
space: this.props.space,
onFinished: this.goToFirstRoom,
createdRooms: this.state.createdRooms
});
case Phase.PrivateScope:
return /*#__PURE__*/_react.default.createElement(SpaceSetupPrivateScope, {
space: this.props.space,
justCreatedOpts: this.props.justCreatedOpts,
onFinished: (invite
/*: boolean*/
) => {
this.setState({
phase: invite ? Phase.PrivateInvite : Phase.PrivateExistingRooms
});
}
});
case Phase.PrivateInvite:
return /*#__PURE__*/_react.default.createElement(SpaceSetupPrivateInvite, {
space: this.props.space,
onFinished: () => this.setState({
phase: Phase.PrivateCreateRooms
})
});
case Phase.PrivateCreateRooms:
return /*#__PURE__*/_react.default.createElement(SpaceSetupFirstRooms, {
space: this.props.space,
title: (0, _languageHandler._t)("What projects are you working on?"),
description: (0, _languageHandler._t)("We'll create rooms for each of them. " + "You can add more later too, including already existing ones."),
onFinished: (createdRooms
/*: boolean*/
) => this.setState({
phase: Phase.Landing,
createdRooms
})
});
case Phase.PrivateExistingRooms:
return /*#__PURE__*/_react.default.createElement(SpaceAddExistingRooms, {
space: this.props.space,
onFinished: () => this.setState({
phase: Phase.Landing
})
});
}
}
render() {
const rightPanel = this.state.showRightPanel && this.state.phase === Phase.Landing ? /*#__PURE__*/_react.default.createElement(_RightPanel.default, {
room: this.props.space,
resizeNotifier: this.props.resizeNotifier
}) : null;
return /*#__PURE__*/_react.default.createElement("main", {
className: "mx_SpaceRoomView"
}, /*#__PURE__*/_react.default.createElement(_ErrorBoundary.default, null, /*#__PURE__*/_react.default.createElement(_MainSplit.default, {
panel: rightPanel,
resizeNotifier: this.props.resizeNotifier
}, this.renderBody())));
}
}
exports.default = SpaceRoomView;
(0, _defineProperty2.default)(SpaceRoomView, "contextType", _MatrixClientContext.default);
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3N0cnVjdHVyZXMvU3BhY2VSb29tVmlldy50c3giXSwibmFtZXMiOlsiUGhhc2UiLCJTcGFjZUZlZWRiYWNrUHJvbXB0Iiwib25DbGljayIsIlNka0NvbmZpZyIsImdldCIsImJ1Z19yZXBvcnRfZW5kcG9pbnRfdXJsIiwiTW9kYWwiLCJjcmVhdGVUcmFja2VkRGlhbG9nIiwiQmV0YUZlZWRiYWNrRGlhbG9nIiwiZmVhdHVyZUlkIiwiUm9vbU1lbWJlckNvdW50Iiwicm9vbSIsImNoaWxkcmVuIiwibWVtYmVycyIsImNvdW50IiwibGVuZ3RoIiwidXNlTXlSb29tTWVtYmVyc2hpcCIsIm1lbWJlcnNoaXAiLCJzZXRNZW1iZXJzaGlwIiwiZ2V0TXlNZW1iZXJzaGlwIiwiU3BhY2VJbmZvIiwic3BhY2UiLCJqb2luUnVsZSIsImdldEpvaW5SdWxlIiwidmlzaWJpbGl0eVNlY3Rpb24iLCJkZWZhdWx0RGlzcGF0Y2hlciIsImRpc3BhdGNoIiwiYWN0aW9uIiwiQWN0aW9uIiwiU2V0UmlnaHRQYW5lbFBoYXNlIiwicGhhc2UiLCJSaWdodFBhbmVsUGhhc2VzIiwiUm9vbU1lbWJlckxpc3QiLCJyZWZpcmVQYXJhbXMiLCJvbkJldGFDbGljayIsIlZpZXdVc2VyU2V0dGluZ3MiLCJpbml0aWFsVGFiSWQiLCJVU0VSX0xBQlNfVEFCIiwiU3BhY2VQcmV2aWV3Iiwib25Kb2luQnV0dG9uQ2xpY2tlZCIsIm9uUmVqZWN0QnV0dG9uQ2xpY2tlZCIsImNsaSIsIk1hdHJpeENsaWVudENvbnRleHQiLCJteU1lbWJlcnNoaXAiLCJidXN5Iiwic2V0QnVzeSIsInNwYWNlc0VuYWJsZWQiLCJTZXR0aW5nc1N0b3JlIiwiZ2V0VmFsdWUiLCJpbnZpdGVyU2VjdGlvbiIsImpvaW5CdXR0b25zIiwiZGlzIiwicm9vbV9pZCIsInJvb21JZCIsImludml0ZVNlbmRlciIsImdldE1lbWJlciIsImdldFVzZXJJZCIsImV2ZW50cyIsIm1lbWJlciIsImdldFNlbmRlciIsImludml0ZXIiLCJuYW1lIiwidG9waWMiLCJyZWYiLCJzcGFjZU5hbWUiLCJhIiwic3ViIiwiU3BhY2VMYW5kaW5nQWRkQnV0dG9uIiwib25OZXdSb29tQWRkZWQiLCJtZW51RGlzcGxheWVkIiwiaGFuZGxlIiwib3Blbk1lbnUiLCJjbG9zZU1lbnUiLCJjb250ZXh0TWVudSIsInJlY3QiLCJjdXJyZW50IiwiZ2V0Qm91bmRpbmdDbGllbnRSZWN0IiwibGVmdCIsIndpbmRvdyIsInBhZ2VYT2Zmc2V0IiwiYm90dG9tIiwicGFnZVlPZmZzZXQiLCJDaGV2cm9uRmFjZSIsIk5vbmUiLCJlIiwicHJldmVudERlZmF1bHQiLCJzdG9wUHJvcGFnYXRpb24iLCJhZGRlZCIsIlNwYWNlTGFuZGluZyIsInVzZXJJZCIsImludml0ZUJ1dHRvbiIsImNhbkludml0ZSIsImNhbkFkZFJvb21zIiwiY3VycmVudFN0YXRlIiwibWF5U2VuZFN0YXRlRXZlbnQiLCJFdmVudFR5cGUiLCJTcGFjZUNoaWxkIiwicmVmcmVzaFRva2VuIiwiZm9yY2VVcGRhdGUiLCJhZGRSb29tQnV0dG9uIiwic2V0dGluZ3NCdXR0b24iLCJvbk1lbWJlcnNDbGljayIsInRhZ3MiLCJzaG93Um9vbSIsIlNwYWNlU2V0dXBGaXJzdFJvb21zIiwidGl0bGUiLCJkZXNjcmlwdGlvbiIsIm9uRmluaXNoZWQiLCJlcnJvciIsInNldEVycm9yIiwibnVtRmllbGRzIiwicGxhY2Vob2xkZXJzIiwicm9vbU5hbWVzIiwic2V0Um9vbU5hbWUiLCJmaWVsZHMiLCJBcnJheSIsImZpbGwiLCJtYXAiLCJfIiwiaSIsImV2IiwidGFyZ2V0IiwidmFsdWUiLCJvbk5leHRDbGljayIsImZpbHRlcmVkUm9vbU5hbWVzIiwidHJpbSIsImZpbHRlciIsIkJvb2xlYW4iLCJQcm9taXNlIiwiYWxsIiwiY3JlYXRlT3B0cyIsInByZXNldCIsIlByZXNldCIsIlB1YmxpY0NoYXQiLCJQcml2YXRlQ2hhdCIsInNwaW5uZXIiLCJlbmNyeXB0aW9uIiwiYW5kVmlldyIsImlubGluZUVycm9ycyIsInBhcmVudFNwYWNlIiwiY29uc29sZSIsImJ1dHRvbkxhYmVsIiwic29tZSIsIlNwYWNlQWRkRXhpc3RpbmdSb29tcyIsIlNwYWNlU2V0dXBQdWJsaWNTaGFyZSIsImp1c3RDcmVhdGVkT3B0cyIsImNyZWF0ZWRSb29tcyIsIlNwYWNlU2V0dXBQcml2YXRlU2NvcGUiLCJ2YWxpZGF0ZUVtYWlsUnVsZXMiLCJydWxlcyIsImtleSIsInRlc3QiLCJFbWFpbCIsImxvb2tzVmFsaWQiLCJpbnZhbGlkIiwiU3BhY2VTZXR1cFByaXZhdGVJbnZpdGUiLCJmaWVsZFJlZnMiLCJlbWFpbEFkZHJlc3NlcyIsInNldEVtYWlsQWRkcmVzcyIsImZpZWxkUmVmIiwidmFsaWQiLCJ2YWxpZGF0ZSIsImFsbG93RW1wdHkiLCJmb2N1cyIsImZvY3VzZWQiLCJ0YXJnZXRJZHMiLCJyZXN1bHQiLCJmYWlsZWRVc2VycyIsIk9iamVjdCIsImtleXMiLCJzdGF0ZXMiLCJsb2ciLCJjc3ZVc2VycyIsImpvaW4iLCJlcnIiLCJiIiwibGluayIsIlNwYWNlUm9vbVZpZXciLCJSZWFjdCIsIlB1cmVDb21wb25lbnQiLCJjb25zdHJ1Y3RvciIsInByb3BzIiwiY29udGV4dCIsInNldFN0YXRlIiwic2hvd1JpZ2h0UGFuZWwiLCJSaWdodFBhbmVsU3RvcmUiLCJnZXRTaGFyZWRJbnN0YW5jZSIsImlzT3BlbkZvclJvb20iLCJwYXlsb2FkIiwiVmlld1VzZXIiLCJTcGFjZU1lbWJlckluZm8iLCJldmVudCIsIlNwYWNlM3BpZE1lbWJlckluZm8iLCJTcGFjZU1lbWJlckxpc3QiLCJjaGlsZFJvb21zIiwiU3BhY2VTdG9yZSIsImluc3RhbmNlIiwiZ2V0Q2hpbGRSb29tcyIsInN1Z2dlc3RlZFJvb21zIiwiYWN0aXZlU3BhY2UiLCJmZXRjaFN1Z2dlc3RlZFJvb21zIiwicm9vbXMiLCJvb2JEYXRhIiwiYXZhdGFyVXJsIiwiYXZhdGFyX3VybCIsImNhbm9uaWNhbF9hbGlhcyIsImFsaWFzZXMiLCJwb3AiLCJMYW5kaW5nIiwiY3JlYXRvciIsImdldFN0YXRlRXZlbnRzIiwiUm9vbUNyZWF0ZSIsInNob3dTZXR1cCIsIlB1YmxpY0NyZWF0ZVJvb21zIiwiUHJpdmF0ZVNjb3BlIiwic3RhdGUiLCJkaXNwYXRjaGVyUmVmIiwicmVnaXN0ZXIiLCJvbkFjdGlvbiIsInJpZ2h0UGFuZWxTdG9yZVRva2VuIiwiYWRkTGlzdGVuZXIiLCJvblJpZ2h0UGFuZWxTdG9yZVVwZGF0ZSIsIm9uIiwib25NeU1lbWJlcnNoaXAiLCJjb21wb25lbnRXaWxsVW5tb3VudCIsInVucmVnaXN0ZXIiLCJyZW1vdmUiLCJvZmYiLCJyZW5kZXJCb2R5IiwiUHVibGljU2hhcmUiLCJnb1RvRmlyc3RSb29tIiwiaW52aXRlIiwiUHJpdmF0ZUludml0ZSIsIlByaXZhdGVFeGlzdGluZ1Jvb21zIiwiUHJpdmF0ZUNyZWF0ZVJvb21zIiwicmVuZGVyIiwicmlnaHRQYW5lbCIsInJlc2l6ZU5vdGlmaWVyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7O0FBZ0JBOztBQUNBOztBQUlBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUVBOztBQUNBOztBQUVBOztBQUNBOztBQUNBOztBQUVBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUlBOztBQUNBOztBQUNBOztBQUNBOztBQUVBOztBQUNBOztBQUNBOztBQWxFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7SUFxRUtBLEssRUFVTDs7V0FWS0EsSztBQUFBQSxFQUFBQSxLLENBQUFBLEs7QUFBQUEsRUFBQUEsSyxDQUFBQSxLO0FBQUFBLEVBQUFBLEssQ0FBQUEsSztBQUFBQSxFQUFBQSxLLENBQUFBLEs7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