Merge pull request #6111 from matrix-org/t3chguy/fix/17365

This commit is contained in:
Michael Telatynski 2021-06-14 22:57:14 +01:00 committed by GitHub
commit 2fd8cc414c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 155 additions and 16 deletions

View file

@ -17,6 +17,9 @@ limitations under the License.
.mx_InviteDialog_addressBar {
display: flex;
flex-direction: row;
// Right margin for the design. We could apply this to the whole dialog, but then the scrollbar
// for the user section gets weird.
margin: 8px 45px 0 0;
.mx_InviteDialog_editor {
flex: 1;
@ -73,7 +76,7 @@ limitations under the License.
}
.mx_InviteDialog_section {
padding-bottom: 10px;
padding-bottom: 4px;
h3 {
font-size: $font-12px;
@ -82,6 +85,14 @@ limitations under the License.
text-transform: uppercase;
}
> p {
margin: 0;
}
> span {
color: $primary-fg-color;
}
.mx_InviteDialog_subname {
margin-bottom: 10px;
margin-top: -10px; // HACK: Positioning with margins is bad
@ -90,6 +101,63 @@ limitations under the License.
}
}
.mx_InviteDialog_section_hidden_suggestions_disclaimer {
padding: 8px 0 16px 0;
font-size: $font-14px;
> span {
color: $primary-fg-color;
font-weight: 600;
}
> p {
margin: 0;
}
}
.mx_InviteDialog_footer {
border-top: 1px solid $input-border-color;
> h3 {
margin: 12px 0;
font-size: $font-12px;
color: $muted-fg-color;
font-weight: bold;
text-transform: uppercase;
}
.mx_InviteDialog_footer_link {
display: flex;
justify-content: space-between;
border-radius: 4px;
border: solid 1px $light-fg-color;
padding: 8px;
> a {
text-decoration: none;
flex-shrink: 1;
overflow: hidden;
text-overflow: ellipsis;
}
}
.mx_InviteDialog_footer_link_copy {
flex-shrink: 0;
cursor: pointer;
margin-left: 20px;
display: inherit;
> div {
mask-image: url($copy-button-url);
background-color: $message-action-bar-fg-color;
margin-left: 5px;
width: 20px;
height: 20px;
background-repeat: no-repeat;
}
}
}
.mx_InviteDialog_roomTile {
cursor: pointer;
padding: 5px 10px;
@ -142,6 +210,7 @@ limitations under the License.
.mx_InviteDialog_roomTile_nameStack {
display: inline-block;
overflow: hidden;
}
.mx_InviteDialog_roomTile_name {
@ -157,6 +226,13 @@ limitations under the License.
margin-left: 7px;
}
.mx_InviteDialog_roomTile_name,
.mx_InviteDialog_roomTile_userId {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.mx_InviteDialog_roomTile_time {
text-align: right;
font-size: $font-12px;
@ -212,22 +288,29 @@ limitations under the License.
.mx_InviteDialog {
// Prevent the dialog from jumping around randomly when elements change.
height: 590px;
height: 600px;
padding-left: 20px; // the design wants some padding on the left
display: flex;
flex-direction: column;
.mx_InviteDialog_content {
overflow: hidden;
}
}
.mx_InviteDialog_userSections {
margin-top: 10px;
margin-top: 4px;
overflow-y: auto;
padding-right: 45px;
height: 455px; // mx_InviteDialog's height minus some for the upper elements
padding: 0 45px 4px 0;
height: calc(100% - 115px); // mx_InviteDialog's height minus some for the upper and lower elements
}
// Right margin for the design. We could apply this to the whole dialog, but then the scrollbar
// for the user section gets weird.
.mx_InviteDialog_helpText,
.mx_InviteDialog_addressBar {
margin-right: 45px;
.mx_InviteDialog_hasFooter .mx_InviteDialog_userSections {
height: calc(100% - 175px);
}
.mx_InviteDialog_helpText {
margin: 0;
}
.mx_InviteDialog_helpText .mx_AccessibleButton_kind_link {

View file

@ -15,6 +15,8 @@ limitations under the License.
*/
import React, { createRef } from 'react';
import classNames from 'classnames';
import {_t, _td} from "../../../languageHandler";
import * as sdk from "../../../index";
import {MatrixClientPeg} from "../../../MatrixClientPeg";
@ -50,6 +52,11 @@ import BaseAvatar from '../avatars/BaseAvatar';
import AccessibleButton from '../elements/AccessibleButton';
import { compare } from '../../../utils/strings';
import { IInvite3PID } from "matrix-js-sdk/src/@types/requests";
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
import { copyPlaintext, selectText } from "../../../utils/strings";
import * as ContextMenu from "../../structures/ContextMenu";
import { toRightOf } from "../../structures/ContextMenu";
import GenericTextContextMenu from "../context_menus/GenericTextContextMenu";
// we have a number of types defined from the Matrix spec which can't reasonably be altered here.
/* eslint-disable camelcase */
@ -351,6 +358,7 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
initialText: "",
};
private closeCopiedTooltip: () => void;
private debounceTimer: NodeJS.Timeout = null; // actually number because we're in the browser
private editorRef = createRef<HTMLInputElement>();
private unmounted = false;
@ -403,6 +411,9 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
componentWillUnmount() {
this.unmounted = true;
// if the Copied tooltip is open then get rid of it, there are ways to close the modal which wouldn't close
// the tooltip otherwise, such as pressing Escape or clicking X really quickly
if (this.closeCopiedTooltip) this.closeCopiedTooltip();
}
private onConsultFirstChange = (ev) => {
@ -1238,6 +1249,25 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
}
}
private async onLinkClick(e) {
e.preventDefault();
selectText(e.target);
}
private onCopyClick = async e => {
e.preventDefault();
const target = e.target; // copy target before we go async and React throws it away
const successful = await copyPlaintext(makeUserPermalink(MatrixClientPeg.get().getUserId()));
const buttonRect = target.getBoundingClientRect();
const { close } = ContextMenu.createMenu(GenericTextContextMenu, {
...toRightOf(buttonRect, 2),
message: successful ? _t("Copied!") : _t("Failed to copy"),
});
// Drop a reference to this close handler for componentWillUnmount
this.closeCopiedTooltip = target.onmouseleave = close;
};
render() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const AccessibleButton = sdk.getComponent("elements.AccessibleButton");
@ -1248,12 +1278,12 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
spinner = <Spinner w={20} h={20} />;
}
let title;
let helpText;
let buttonText;
let goButtonFn;
let consultSection;
let extraSection;
let footer;
let keySharingWarning = <span />;
const identityServersEnabled = SettingsStore.getValue(UIFeature.IdentityServer);
@ -1316,6 +1346,26 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
}
buttonText = _t("Go");
goButtonFn = this.startDm;
extraSection = <div className="mx_InviteDialog_section_hidden_suggestions_disclaimer">
<span>{ _t("Some suggestions may be hidden for privacy.") }</span>
<p>{ _t("If you can't see who youre looking for, send them your invite link below.") }</p>
</div>;
const link = makeUserPermalink(MatrixClientPeg.get().getUserId());
footer = <div className="mx_InviteDialog_footer">
<h3>{ _t("Or send invite link") }</h3>
<div className="mx_InviteDialog_footer_link">
<a href={link} onClick={this.onLinkClick}>
{ link }
</a>
<AccessibleTooltipButton
title={_t("Copy")}
onClick={this.onCopyClick}
className="mx_InviteDialog_footer_link_copy"
>
<div />
</AccessibleTooltipButton>
</div>
</div>
} else if (this.props.kind === KIND_INVITE) {
const room = MatrixClientPeg.get()?.getRoom(this.props.roomId);
const isSpace = SettingsStore.getValue("feature_spaces") && room?.isSpaceRoom();
@ -1377,7 +1427,7 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
title = _t("Transfer");
buttonText = _t("Transfer");
goButtonFn = this.transferCall;
consultSection = <div>
footer = <div>
<label>
<input type="checkbox" checked={this.state.consultFirst} onChange={this.onConsultFirstChange} />
{_t("Consult first")}
@ -1391,7 +1441,9 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
|| (this.state.filterText && this.state.filterText.includes('@'));
return (
<BaseDialog
className='mx_InviteDialog'
className={classNames("mx_InviteDialog", {
mx_InviteDialog_hasFooter: !!footer,
})}
hasCancel={true}
onFinished={this.props.onFinished}
title={title}
@ -1418,8 +1470,9 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
<div className='mx_InviteDialog_userSections'>
{this.renderSection('recents')}
{this.renderSection('suggestions')}
{extraSection}
</div>
{consultSection}
{footer}
</div>
</BaseDialog>
);

View file

@ -2257,6 +2257,9 @@
"Start a conversation with someone using their name or username (like <userId/>).": "Start a conversation with someone using their name or username (like <userId/>).",
"This won't invite them to %(communityName)s. To invite someone to %(communityName)s, click <a>here</a>": "This won't invite them to %(communityName)s. To invite someone to %(communityName)s, click <a>here</a>",
"Go": "Go",
"Some suggestions may be hidden for privacy.": "Some suggestions may be hidden for privacy.",
"If you can't see who youre looking for, send them your invite link below.": "If you can't see who youre looking for, send them your invite link below.",
"Or send invite link": "Or send invite link",
"Unnamed Space": "Unnamed Space",
"Invite to %(roomName)s": "Invite to %(roomName)s",
"Invite someone using their name, email address, username (like <userId/>) or <a>share this space</a>.": "Invite someone using their name, email address, username (like <userId/>) or <a>share this space</a>.",