Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add footer and privacy note to the start dm dialog #6111

Merged
merged 14 commits into from
Jun 14, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 82 additions & 7 deletions res/css/views/dialogs/_InviteDialog.scss
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ limitations under the License.
}

.mx_InviteDialog_section {
padding-bottom: 10px;
padding-bottom: 4px;

h3 {
font-size: $font-12px;
Expand All @@ -82,6 +82,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
Expand All @@ -90,6 +98,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;
t3chguy marked this conversation as resolved.
Show resolved Hide resolved
}
}

.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;
Expand Down Expand Up @@ -212,22 +277,32 @@ 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: 0px 45px 4px 0px;
t3chguy marked this conversation as resolved.
Show resolved Hide resolved
height: calc(100% - 175px); // 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;
margin: 8px 45px 0px 0px;
t3chguy marked this conversation as resolved.
Show resolved Hide resolved
}

.mx_InviteDialog_helpText {
margin:0px;
t3chguy marked this conversation as resolved.
Show resolved Hide resolved
}

.mx_InviteDialog_helpText .mx_AccessibleButton_kind_link {
Expand Down
58 changes: 54 additions & 4 deletions src/components/views/dialogs/InviteDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ import { MatrixCall } from 'matrix-js-sdk/src/webrtc/call';
import {replaceableComponent} from "../../../utils/replaceableComponent";
import {mediaFromMxc} from "../../../customisations/Media";
import {getAddressType} from "../../../UserAddress";
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 */
Expand Down Expand Up @@ -349,6 +354,7 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
initialText: "",
};

private closeCopiedTooltip: () => void;
_debounceTimer: NodeJS.Timeout = null; // actually number because we're in the browser
_editorRef: any = null;

Expand Down Expand Up @@ -400,6 +406,12 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
}
}

componentWillUnmount() {
// 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) => {
this.setState({consultFirst: ev.target.checked});
}
Expand Down Expand Up @@ -1232,6 +1244,25 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
}
}

async onLinkClick(e) {
t3chguy marked this conversation as resolved.
Show resolved Hide resolved
e.preventDefault();
selectText(e.target);
}

async onCopyClick(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");
Expand All @@ -1242,12 +1273,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);
Expand Down Expand Up @@ -1310,6 +1341,24 @@ 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 you’re looking for, send them your invite link below.") }</p>
t3chguy marked this conversation as resolved.
Show resolved Hide resolved
</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>
</div>
} else if (this.props.kind === KIND_INVITE) {
const room = MatrixClientPeg.get()?.getRoom(this.props.roomId);
const isSpace = SettingsStore.getValue("feature_spaces") && room?.isSpaceRoom();
Expand Down Expand Up @@ -1371,7 +1420,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")}
Expand Down Expand Up @@ -1412,8 +1461,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>
);
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -2246,6 +2246,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 you’re looking for, send them your invite link below.": "If you can’t see who you’re 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>.",
Expand Down