Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 5d027ff

Browse files
authored
Merge pull request #5694 from robintown/show-invite-reasons
Show invite reasons
2 parents 4d72af7 + 2477258 commit 5d027ff

File tree

9 files changed

+146
-33
lines changed

9 files changed

+146
-33
lines changed

res/css/views/rooms/_RoomPreviewBar.scss

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,35 @@ limitations under the License.
4040
word-break: break-word;
4141
}
4242

43+
.mx_RoomPreviewBar_reason {
44+
text-align: left;
45+
background-color: $primary-bg-color;
46+
border: 1px solid $invite-reason-border-color;
47+
border-radius: 10px;
48+
padding: 0 16px 12px 16px;
49+
margin: 5px 0 20px 0;
50+
51+
div {
52+
pointer-events: none;
53+
}
54+
55+
.mx_EventTile_msgOption {
56+
display: none;
57+
}
58+
59+
.mx_MatrixChat_useCompactLayout & {
60+
padding-top: 9px;
61+
}
62+
63+
&.mx_EventTilePreview_faded {
64+
cursor: pointer;
65+
66+
.mx_SenderProfile, .mx_EventTile_avatar {
67+
opacity: 0.3;
68+
}
69+
}
70+
}
71+
4372
.mx_Spinner {
4473
width: auto;
4574
height: auto;

res/themes/dark/css/_dark.scss

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ $message-body-panel-fg-color: $primary-fg-color;
209209
// Appearance tab colors
210210
$appearance-tab-border-color: $room-highlight-color;
211211

212+
$invite-reason-border-color: $room-highlight-color;
213+
212214
// blur amounts for left left panel (only for element theme, used in _mods.scss)
213215
$roomlist-background-blur-amount: 60px;
214216
$groupFilterPanel-background-blur-amount: 30px;

res/themes/legacy-dark/css/_legacy-dark.scss

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,8 @@ $message-body-panel-fg-color: $primary-fg-color;
204204
// Appearance tab colors
205205
$appearance-tab-border-color: $room-highlight-color;
206206

207+
$invite-reason-border-color: $room-highlight-color;
208+
207209
$composer-shadow-color: tranparent;
208210

209211
// ***** Mixins! *****

res/themes/legacy-light/css/_legacy-light.scss

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,8 @@ $message-body-panel-fg-color: $muted-fg-color;
333333
// FontSlider colors
334334
$appearance-tab-border-color: $input-darker-bg-color;
335335

336+
$invite-reason-border-color: $input-darker-bg-color;
337+
336338
$composer-shadow-color: tranparent;
337339

338340
// ***** Mixins! *****

res/themes/light/css/_light.scss

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,8 @@ $message-body-panel-fg-color: $muted-fg-color;
331331
// FontSlider colors
332332
$appearance-tab-border-color: $input-darker-bg-color;
333333

334+
$invite-reason-border-color: $input-darker-bg-color;
335+
334336
// blur amounts for left left panel (only for element theme, used in _mods.scss)
335337
$roomlist-background-blur-amount: 40px;
336338
$groupFilterPanel-background-blur-amount: 20px;

src/components/views/elements/EventTilePreview.tsx

Lines changed: 57 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import classnames from 'classnames';
1919
import { MatrixEvent } from 'matrix-js-sdk/src/models/event';
2020

2121
import * as Avatar from '../../../Avatar';
22-
import { MatrixClientPeg } from '../../../MatrixClientPeg';
2322
import EventTile from '../rooms/EventTile';
2423
import SettingsStore from "../../../settings/SettingsStore";
2524
import {Layout} from "../../../settings/Layout";
@@ -41,61 +40,81 @@ interface IProps {
4140
* classnames to apply to the wrapper of the preview
4241
*/
4342
className: string;
43+
44+
/**
45+
* The ID of the displayed user
46+
*/
47+
userId: string;
48+
49+
/**
50+
* The display name of the displayed user
51+
*/
52+
displayName?: string;
53+
54+
/**
55+
* The mxc:// avatar URL of the displayed user
56+
*/
57+
avatarUrl?: string;
58+
59+
/**
60+
* Whether the EventTile should appear faded
61+
*/
62+
faded?: boolean;
63+
64+
/**
65+
* Callback for when the component is clicked
66+
*/
67+
onClick?: () => void;
4468
}
4569

46-
/* eslint-disable camelcase */
4770
interface IState {
48-
userId: string;
49-
displayname: string;
50-
avatar_url: string;
71+
message: string;
72+
faded: boolean;
73+
eventTileKey: number;
5174
}
52-
/* eslint-enable camelcase */
5375

5476
const AVATAR_SIZE = 32;
5577

5678
@replaceableComponent("views.elements.EventTilePreview")
5779
export default class EventTilePreview extends React.Component<IProps, IState> {
5880
constructor(props: IProps) {
5981
super(props);
60-
6182
this.state = {
62-
userId: "@erim:fink.fink",
63-
displayname: "Erimayas Fink",
64-
avatar_url: null,
83+
message: props.message,
84+
faded: !!props.faded,
85+
eventTileKey: 0,
6586
};
6687
}
6788

68-
async componentDidMount() {
69-
// Fetch current user data
70-
const client = MatrixClientPeg.get();
71-
const userId = client.getUserId();
72-
const profileInfo = await client.getProfileInfo(userId);
73-
const avatarUrl = profileInfo.avatar_url;
74-
89+
changeMessage(message: string) {
7590
this.setState({
76-
userId,
77-
displayname: profileInfo.displayname,
78-
avatar_url: avatarUrl,
91+
message,
92+
// Change the EventTile key to force React to create a new instance
93+
eventTileKey: this.state.eventTileKey + 1,
7994
});
8095
}
8196

82-
private fakeEvent({userId, displayname, avatar_url: avatarUrl}: IState) {
97+
unfade() {
98+
this.setState({ faded: false });
99+
}
100+
101+
private fakeEvent({message}: IState) {
83102
// Fake it till we make it
84103
/* eslint-disable quote-props */
85104
const rawEvent = {
86105
type: "m.room.message",
87-
sender: userId,
106+
sender: this.props.userId,
88107
content: {
89108
"m.new_content": {
90109
msgtype: "m.text",
91-
body: this.props.message,
92-
displayname: displayname,
93-
avatar_url: avatarUrl,
110+
body: message,
111+
displayname: this.props.displayName,
112+
avatar_url: this.props.avatarUrl,
94113
},
95114
msgtype: "m.text",
96-
body: this.props.message,
97-
displayname: displayname,
98-
avatar_url: avatarUrl,
115+
body: message,
116+
displayname: this.props.displayName,
117+
avatar_url: this.props.avatarUrl,
99118
},
100119
unsigned: {
101120
age: 97,
@@ -108,12 +127,15 @@ export default class EventTilePreview extends React.Component<IProps, IState> {
108127

109128
// Fake it more
110129
event.sender = {
111-
name: displayname,
112-
userId: userId,
130+
name: this.props.displayName,
131+
userId: this.props.userId,
113132
getAvatarUrl: (..._) => {
114-
return Avatar.avatarUrlForUser({avatarUrl}, AVATAR_SIZE, AVATAR_SIZE, "crop");
133+
return Avatar.avatarUrlForUser(
134+
{ avatarUrl: this.props.avatarUrl },
135+
AVATAR_SIZE, AVATAR_SIZE, "crop",
136+
);
115137
},
116-
getMxcAvatarUrl: () => avatarUrl,
138+
getMxcAvatarUrl: () => this.props.avatarUrl,
117139
};
118140

119141
return event;
@@ -125,10 +147,12 @@ export default class EventTilePreview extends React.Component<IProps, IState> {
125147
const className = classnames(this.props.className, {
126148
"mx_IRCLayout": this.props.layout == Layout.IRC,
127149
"mx_GroupLayout": this.props.layout == Layout.Group,
150+
"mx_EventTilePreview_faded": this.state.faded,
128151
});
129152

130-
return <div className={className}>
153+
return <div className={className} onClick={this.props.onClick}>
131154
<EventTile
155+
key={this.state.eventTileKey}
132156
mxEvent={event}
133157
layout={this.props.layout}
134158
enableFlair={SettingsStore.getValue(UIFeature.Flair)}

src/components/views/rooms/RoomPreviewBar.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import classNames from 'classnames';
2525
import { _t } from '../../../languageHandler';
2626
import SdkConfig from "../../../SdkConfig";
2727
import IdentityAuthClient from '../../../IdentityAuthClient';
28+
import SettingsStore from "../../../settings/SettingsStore";
2829
import {CommunityPrototypeStore} from "../../../stores/CommunityPrototypeStore";
2930
import {UPDATE_EVENT} from "../../../stores/AsyncStore";
3031
import {replaceableComponent} from "../../../utils/replaceableComponent";
@@ -302,10 +303,12 @@ export default class RoomPreviewBar extends React.Component {
302303
const brand = SdkConfig.get().brand;
303304
const Spinner = sdk.getComponent('elements.Spinner');
304305
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
306+
const EventTilePreview = sdk.getComponent('elements.EventTilePreview');
305307

306308
let showSpinner = false;
307309
let title;
308310
let subTitle;
311+
let reasonElement;
309312
let primaryActionHandler;
310313
let primaryActionLabel;
311314
let secondaryActionHandler;
@@ -491,6 +494,29 @@ export default class RoomPreviewBar extends React.Component {
491494
primaryActionLabel = _t("Accept");
492495
}
493496

497+
const myUserId = MatrixClientPeg.get().getUserId();
498+
const reason = this.props.room.currentState.getMember(myUserId).events.member.event.content.reason;
499+
if (reason) {
500+
this.reasonElement = React.createRef();
501+
// We hide the reason for invitation by default, since it can be a
502+
// vector for spam/harassment.
503+
const showReason = () => {
504+
this.reasonElement.current.unfade();
505+
this.reasonElement.current.changeMessage(reason);
506+
};
507+
reasonElement = <EventTilePreview
508+
ref={this.reasonElement}
509+
onClick={showReason}
510+
className="mx_RoomPreviewBar_reason"
511+
message={_t("Invite messages are hidden by default. Click to show the message.")}
512+
layout={SettingsStore.getValue("layout")}
513+
userId={inviteMember.userId}
514+
displayName={inviteMember.rawDisplayName}
515+
avatarUrl={inviteMember.events.member.event.content.avatar_url}
516+
faded={true}
517+
/>;
518+
}
519+
494520
primaryActionHandler = this.props.onJoinClick;
495521
secondaryActionLabel = _t("Reject");
496522
secondaryActionHandler = this.props.onRejectClick;
@@ -582,6 +608,7 @@ export default class RoomPreviewBar extends React.Component {
582608
{ titleElement }
583609
{ subTitleElements }
584610
</div>
611+
{ reasonElement }
585612
<div className="mx_RoomPreviewBar_actions">
586613
{ secondaryButton }
587614
{ extraComponents }

src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ limitations under the License.
1818
import React from 'react';
1919
import {_t} from "../../../../../languageHandler";
2020
import SdkConfig from "../../../../../SdkConfig";
21+
import { MatrixClientPeg } from '../../../../../MatrixClientPeg';
2122
import SettingsStore from "../../../../../settings/SettingsStore";
2223
import { enumerateThemes } from "../../../../../theme";
2324
import ThemeWatcher from "../../../../../settings/watchers/ThemeWatcher";
@@ -63,6 +64,10 @@ interface IState extends IThemeState {
6364
systemFont: string;
6465
showAdvanced: boolean;
6566
layout: Layout;
67+
// User profile data for the message preview
68+
userId: string;
69+
displayName: string;
70+
avatarUrl: string;
6671
}
6772

6873
@replaceableComponent("views.settings.tabs.user.AppearanceUserSettingsTab")
@@ -84,9 +89,25 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
8489
systemFont: SettingsStore.getValue("systemFont"),
8590
showAdvanced: false,
8691
layout: SettingsStore.getValue("layout"),
92+
userId: "@erim:fink.fink",
93+
displayName: "Erimayas Fink",
94+
avatarUrl: null,
8795
};
8896
}
8997

98+
async componentDidMount() {
99+
// Fetch the current user profile for the message preview
100+
const client = MatrixClientPeg.get();
101+
const userId = client.getUserId();
102+
const profileInfo = await client.getProfileInfo(userId);
103+
104+
this.setState({
105+
userId,
106+
displayName: profileInfo.displayname,
107+
avatarUrl: profileInfo.avatar_url,
108+
});
109+
}
110+
90111
private calculateThemeState(): IThemeState {
91112
// We have to mirror the logic from ThemeWatcher.getEffectiveTheme so we
92113
// show the right values for things.
@@ -307,6 +328,9 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
307328
className="mx_AppearanceUserSettingsTab_fontSlider_preview"
308329
message={this.MESSAGE_PREVIEW_TEXT}
309330
layout={this.state.layout}
331+
userId={this.state.userId}
332+
displayName={this.state.displayName}
333+
avatarUrl={this.state.avatarUrl}
310334
/>
311335
<div className="mx_AppearanceUserSettingsTab_fontSlider">
312336
<div className="mx_AppearanceUserSettingsTab_fontSlider_smallText">Aa</div>

src/i18n/strings/en_EN.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1578,6 +1578,7 @@
15781578
"Start chatting": "Start chatting",
15791579
"Do you want to join %(roomName)s?": "Do you want to join %(roomName)s?",
15801580
"<userName/> invited you": "<userName/> invited you",
1581+
"Invite messages are hidden by default. Click to show the message.": "Invite messages are hidden by default. Click to show the message.",
15811582
"Reject": "Reject",
15821583
"Reject & Ignore user": "Reject & Ignore user",
15831584
"You're previewing %(roomName)s. Want to join it?": "You're previewing %(roomName)s. Want to join it?",

0 commit comments

Comments
 (0)