diff --git a/res/css/views/dialogs/_InviteDialog.scss b/res/css/views/dialogs/_InviteDialog.scss index d8ff56663ab..2e48b5d8e93 100644 --- a/res/css/views/dialogs/_InviteDialog.scss +++ b/res/css/views/dialogs/_InviteDialog.scss @@ -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 { diff --git a/src/components/views/dialogs/InviteDialog.tsx b/src/components/views/dialogs/InviteDialog.tsx index d90214110fe..778744b783b 100644 --- a/src/components/views/dialogs/InviteDialog.tsx +++ b/src/components/views/dialogs/InviteDialog.tsx @@ -14,7 +14,9 @@ See the License for the specific language governing permissions and limitations under the License. */ -import React, {createRef} from 'react'; +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 void; private debounceTimer: NodeJS.Timeout = null; // actually number because we're in the browser private editorRef = createRef(); private unmounted = false; @@ -403,6 +411,9 @@ export default class InviteDialog extends React.PureComponent { @@ -1238,6 +1249,25 @@ export default class InviteDialog extends React.PureComponent { + 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; } - let title; let helpText; let buttonText; let goButtonFn; - let consultSection; + let extraSection; + let footer; let keySharingWarning = ; const identityServersEnabled = SettingsStore.getValue(UIFeature.IdentityServer); @@ -1316,6 +1346,26 @@ export default class InviteDialog extends React.PureComponent + { _t("Some suggestions may be hidden for privacy.") } +

{ _t("If you can't see who you’re looking for, send them your invite link below.") }

+ ; + const link = makeUserPermalink(MatrixClientPeg.get().getUserId()); + footer =
+

{ _t("Or send invite link") }

+
+ + { link } + + +
+ +
+
} 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 + footer =
- {consultSection} + {footer}
); diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 874dc11bd25..17d6f64c460 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2257,6 +2257,9 @@ "Start a conversation with someone using their name or username (like ).": "Start a conversation with someone using their name or username (like ).", "This won't invite them to %(communityName)s. To invite someone to %(communityName)s, click here": "This won't invite them to %(communityName)s. To invite someone to %(communityName)s, click here", "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 ) or share this space.": "Invite someone using their name, email address, username (like ) or share this space.",