Merge pull request #5847 from matrix-org/jryans/reason-message-tweaks

Tweak appearance of invite reason
This commit is contained in:
J. Ryan Stinnett 2021-04-12 13:36:20 +01:00 committed by GitHub
commit 098a8711a7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 123 additions and 91 deletions

View file

@ -123,6 +123,7 @@
@import "./views/elements/_ImageView.scss"; @import "./views/elements/_ImageView.scss";
@import "./views/elements/_InfoTooltip.scss"; @import "./views/elements/_InfoTooltip.scss";
@import "./views/elements/_InlineSpinner.scss"; @import "./views/elements/_InlineSpinner.scss";
@import "./views/elements/_InviteReason.scss";
@import "./views/elements/_ManageIntegsButton.scss"; @import "./views/elements/_ManageIntegsButton.scss";
@import "./views/elements/_MiniAvatarUploader.scss"; @import "./views/elements/_MiniAvatarUploader.scss";
@import "./views/elements/_PowerSelector.scss"; @import "./views/elements/_PowerSelector.scss";

View file

@ -0,0 +1,54 @@
/*
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.
*/
.mx_InviteReason {
position: relative;
margin-bottom: 1em;
.mx_InviteReason_reason {
visibility: visible;
}
.mx_InviteReason_view {
display: none;
position: absolute;
inset: 0;
justify-content: center;
align-items: center;
cursor: pointer;
color: $secondary-fg-color;
&::before {
content: "";
margin-right: 8px;
background-color: $secondary-fg-color;
mask-image: url('$(res)/img/feather-customised/eye.svg');
display: inline-block;
width: 18px;
height: 14px;
}
}
}
.mx_InviteReason_hidden {
.mx_InviteReason_reason {
visibility: hidden;
}
.mx_InviteReason_view {
display: flex;
}
}

View file

@ -40,35 +40,6 @@ limitations under the License.
word-break: break-word; word-break: break-word;
} }
.mx_RoomPreviewBar_reason {
text-align: left;
background-color: $primary-bg-color;
border: 1px solid $invite-reason-border-color;
border-radius: 10px;
padding: 0 16px 12px 16px;
margin: 5px 0 20px 0;
div {
pointer-events: none;
}
.mx_EventTile_msgOption {
display: none;
}
.mx_MatrixChat_useCompactLayout & {
padding-top: 9px;
}
&.mx_EventTilePreview_faded {
cursor: pointer;
.mx_SenderProfile, .mx_EventTile_avatar {
opacity: 0.3;
}
}
}
.mx_Spinner { .mx_Spinner {
width: auto; width: auto;
height: auto; height: auto;

View file

@ -209,8 +209,6 @@ $message-body-panel-fg-color: $primary-fg-color;
// Appearance tab colors // Appearance tab colors
$appearance-tab-border-color: $room-highlight-color; $appearance-tab-border-color: $room-highlight-color;
$invite-reason-border-color: $room-highlight-color;
// blur amounts for left left panel (only for element theme, used in _mods.scss) // blur amounts for left left panel (only for element theme, used in _mods.scss)
$roomlist-background-blur-amount: 60px; $roomlist-background-blur-amount: 60px;
$groupFilterPanel-background-blur-amount: 30px; $groupFilterPanel-background-blur-amount: 30px;

View file

@ -204,8 +204,6 @@ $message-body-panel-fg-color: $primary-fg-color;
// Appearance tab colors // Appearance tab colors
$appearance-tab-border-color: $room-highlight-color; $appearance-tab-border-color: $room-highlight-color;
$invite-reason-border-color: $room-highlight-color;
$composer-shadow-color: tranparent; $composer-shadow-color: tranparent;
// ***** Mixins! ***** // ***** Mixins! *****

View file

@ -333,8 +333,6 @@ $message-body-panel-fg-color: $muted-fg-color;
// FontSlider colors // FontSlider colors
$appearance-tab-border-color: $input-darker-bg-color; $appearance-tab-border-color: $input-darker-bg-color;
$invite-reason-border-color: $input-darker-bg-color;
$composer-shadow-color: tranparent; $composer-shadow-color: tranparent;
// ***** Mixins! ***** // ***** Mixins! *****

View file

@ -331,8 +331,6 @@ $message-body-panel-fg-color: $muted-fg-color;
// FontSlider colors // FontSlider colors
$appearance-tab-border-color: $input-darker-bg-color; $appearance-tab-border-color: $input-darker-bg-color;
$invite-reason-border-color: $input-darker-bg-color;
// blur amounts for left left panel (only for element theme, used in _mods.scss) // blur amounts for left left panel (only for element theme, used in _mods.scss)
$roomlist-background-blur-amount: 40px; $roomlist-background-blur-amount: 40px;
$groupFilterPanel-background-blur-amount: 20px; $groupFilterPanel-background-blur-amount: 20px;

View file

@ -55,22 +55,10 @@ interface IProps {
* The mxc:// avatar URL of the displayed user * The mxc:// avatar URL of the displayed user
*/ */
avatarUrl?: string; avatarUrl?: string;
/**
* Whether the EventTile should appear faded
*/
faded?: boolean;
/**
* Callback for when the component is clicked
*/
onClick?: () => void;
} }
interface IState { interface IState {
message: string; message: string;
faded: boolean;
eventTileKey: number;
} }
const AVATAR_SIZE = 32; const AVATAR_SIZE = 32;
@ -81,23 +69,9 @@ export default class EventTilePreview extends React.Component<IProps, IState> {
super(props); super(props);
this.state = { this.state = {
message: props.message, message: props.message,
faded: !!props.faded,
eventTileKey: 0,
}; };
} }
changeMessage(message: string) {
this.setState({
message,
// Change the EventTile key to force React to create a new instance
eventTileKey: this.state.eventTileKey + 1,
});
}
unfade() {
this.setState({ faded: false });
}
private fakeEvent({message}: IState) { private fakeEvent({message}: IState) {
// Fake it till we make it // Fake it till we make it
/* eslint-disable quote-props */ /* eslint-disable quote-props */
@ -147,12 +121,10 @@ export default class EventTilePreview extends React.Component<IProps, IState> {
const className = classnames(this.props.className, { const className = classnames(this.props.className, {
"mx_IRCLayout": this.props.layout == Layout.IRC, "mx_IRCLayout": this.props.layout == Layout.IRC,
"mx_GroupLayout": this.props.layout == Layout.Group, "mx_GroupLayout": this.props.layout == Layout.Group,
"mx_EventTilePreview_faded": this.state.faded,
}); });
return <div className={className} onClick={this.props.onClick}> return <div className={className}>
<EventTile <EventTile
key={this.state.eventTileKey}
mxEvent={event} mxEvent={event}
layout={this.props.layout} layout={this.props.layout}
enableFlair={SettingsStore.getValue(UIFeature.Flair)} enableFlair={SettingsStore.getValue(UIFeature.Flair)}

View file

@ -0,0 +1,62 @@
/*
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.
*/
import classNames from "classnames";
import React from "react";
import { _t } from "../../../languageHandler";
import { replaceableComponent } from "../../../utils/replaceableComponent";
interface IProps {
reason: string;
}
interface IState {
hidden: boolean;
}
@replaceableComponent("views.elements.InviteReason")
export default class InviteReason extends React.PureComponent<IProps, IState> {
constructor(props) {
super(props);
this.state = {
// We hide the reason for invitation by default, since it can be a
// vector for spam/harassment.
hidden: true,
};
}
onViewClick = () => {
this.setState({
hidden: false,
});
}
render() {
const classes = classNames({
"mx_InviteReason": true,
"mx_InviteReason_hidden": this.state.hidden,
});
return <div className={classes}>
<div className="mx_InviteReason_reason">{this.props.reason}</div>
<div className="mx_InviteReason_view"
onClick={this.onViewClick}
>
{_t("View message")}
</div>
</div>;
}
}

View file

@ -1,7 +1,5 @@
/* /*
Copyright 2015, 2016 OpenMarket Ltd Copyright 2015-2021 The Matrix.org Foundation C.I.C.
Copyright 2017 Vector Creations Ltd
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -25,10 +23,10 @@ import classNames from 'classnames';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import SdkConfig from "../../../SdkConfig"; import SdkConfig from "../../../SdkConfig";
import IdentityAuthClient from '../../../IdentityAuthClient'; import IdentityAuthClient from '../../../IdentityAuthClient';
import SettingsStore from "../../../settings/SettingsStore";
import {CommunityPrototypeStore} from "../../../stores/CommunityPrototypeStore"; import {CommunityPrototypeStore} from "../../../stores/CommunityPrototypeStore";
import {UPDATE_EVENT} from "../../../stores/AsyncStore"; import {UPDATE_EVENT} from "../../../stores/AsyncStore";
import {replaceableComponent} from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import InviteReason from "../elements/InviteReason";
const MessageCase = Object.freeze({ const MessageCase = Object.freeze({
NotLoggedIn: "NotLoggedIn", NotLoggedIn: "NotLoggedIn",
@ -303,7 +301,6 @@ export default class RoomPreviewBar extends React.Component {
const brand = SdkConfig.get().brand; const brand = SdkConfig.get().brand;
const Spinner = sdk.getComponent('elements.Spinner'); const Spinner = sdk.getComponent('elements.Spinner');
const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
const EventTilePreview = sdk.getComponent('elements.EventTilePreview');
let showSpinner = false; let showSpinner = false;
let title; let title;
@ -497,24 +494,7 @@ export default class RoomPreviewBar extends React.Component {
const myUserId = MatrixClientPeg.get().getUserId(); const myUserId = MatrixClientPeg.get().getUserId();
const reason = this.props.room.currentState.getMember(myUserId).events.member.event.content.reason; const reason = this.props.room.currentState.getMember(myUserId).events.member.event.content.reason;
if (reason) { if (reason) {
this.reasonElement = React.createRef(); reasonElement = <InviteReason reason={reason} />;
// We hide the reason for invitation by default, since it can be a
// vector for spam/harassment.
const showReason = () => {
this.reasonElement.current.unfade();
this.reasonElement.current.changeMessage(reason);
};
reasonElement = <EventTilePreview
ref={this.reasonElement}
onClick={showReason}
className="mx_RoomPreviewBar_reason"
message={_t("Invite messages are hidden by default. Click to show the message.")}
layout={SettingsStore.getValue("layout")}
userId={inviteMember.userId}
displayName={inviteMember.rawDisplayName}
avatarUrl={inviteMember.events.member.event.content.avatar_url}
faded={true}
/>;
} }
primaryActionHandler = this.props.onJoinClick; primaryActionHandler = this.props.onJoinClick;

View file

@ -1577,7 +1577,6 @@
"Start chatting": "Start chatting", "Start chatting": "Start chatting",
"Do you want to join %(roomName)s?": "Do you want to join %(roomName)s?", "Do you want to join %(roomName)s?": "Do you want to join %(roomName)s?",
"<userName/> invited you": "<userName/> invited you", "<userName/> invited you": "<userName/> invited you",
"Invite messages are hidden by default. Click to show the message.": "Invite messages are hidden by default. Click to show the message.",
"Reject": "Reject", "Reject": "Reject",
"Reject & Ignore user": "Reject & Ignore user", "Reject & Ignore user": "Reject & Ignore user",
"You're previewing %(roomName)s. Want to join it?": "You're previewing %(roomName)s. Want to join it?", "You're previewing %(roomName)s. Want to join it?": "You're previewing %(roomName)s. Want to join it?",
@ -1924,6 +1923,7 @@
"Rotate clockwise": "Rotate clockwise", "Rotate clockwise": "Rotate clockwise",
"Download this file": "Download this file", "Download this file": "Download this file",
"Information": "Information", "Information": "Information",
"View message": "View message",
"Language Dropdown": "Language Dropdown", "Language Dropdown": "Language Dropdown",
"%(nameList)s %(transitionList)s": "%(nameList)s %(transitionList)s", "%(nameList)s %(transitionList)s": "%(nameList)s %(transitionList)s",
"%(severalUsers)sjoined %(count)s times|other": "%(severalUsers)sjoined %(count)s times", "%(severalUsers)sjoined %(count)s times|other": "%(severalUsers)sjoined %(count)s times",