mirror of
https://github.com/vector-im/element-web.git
synced 2024-11-16 13:14:58 +08:00
Name lists on invite dialog (#8046)
* Place room tiles with grid Signed-off-by: Suguru Hirahara <luixxiul@users.noreply.github.com> * Set padding inside of name stack Signed-off-by: Suguru Hirahara <luixxiul@users.noreply.github.com> * Remove overflow:hidden (to be cancelled) Signed-off-by: Suguru Hirahara <luixxiul@users.noreply.github.com> * Replace text-align with margin Signed-off-by: Suguru Hirahara <luixxiul@users.noreply.github.com> * Style invite failure dialog with display:grid Signed-off-by: Suguru Hirahara <luixxiul@users.noreply.github.com> * Merge style rules of room tiles and tiles on invitation failure dialog Signed-off-by: Suguru Hirahara <luixxiul@users.noreply.github.com> * Normalize avatar size for multiInviterError Signed-off-by: Suguru Hirahara <luixxiul@users.noreply.github.com> * Set text overflow with ellipsis Signed-off-by: Suguru Hirahara <luixxiul@users.noreply.github.com> * Use spacing variables Signed-off-by: Suguru Hirahara <luixxiul@users.noreply.github.com> * Set narrow gap to nameStack Signed-off-by: Suguru Hirahara <luixxiul@users.noreply.github.com> * Rename mx_InviteDialog_inviterErrorTile_error Signed-off-by: Suguru Hirahara <luixxiul@users.noreply.github.com> * Create mx_InviteDialog_tile Signed-off-by: Suguru Hirahara <luixxiul@users.noreply.github.com> * Set padding to room tiles only Signed-off-by: Suguru Hirahara <luixxiul@users.noreply.github.com> * Remove space between name / userID and time (there is gap by default) Signed-off-by: Suguru Hirahara <luixxiul@users.noreply.github.com> * Remove the margin from the last child Signed-off-by: Suguru Hirahara <luixxiul@users.noreply.github.com>
This commit is contained in:
parent
67cace7de7
commit
12dd5a7ef0
@ -146,94 +146,6 @@ limitations under the License.
|
||||
}
|
||||
}
|
||||
|
||||
.mx_InviteDialog_roomTile {
|
||||
cursor: pointer;
|
||||
padding: 5px 10px;
|
||||
|
||||
&:hover {
|
||||
background-color: $header-panel-bg-color;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
* {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.mx_InviteDialog_roomTile_avatarStack {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
|
||||
& > * {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_InviteDialog_roomTile_selected {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 36px;
|
||||
background-color: $username-variant1-color;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
grid-column: 1;
|
||||
grid-row: 1;
|
||||
mask-image: url("$(res)/img/feather-customised/check.svg");
|
||||
mask-size: 100%;
|
||||
mask-repeat: no-repeat;
|
||||
position: absolute;
|
||||
top: 6px; // 50%
|
||||
left: 6px; // 50%
|
||||
background-color: #ffffff; // this is fine without a var because it's for both themes
|
||||
}
|
||||
}
|
||||
|
||||
.mx_InviteDialog_roomTile_nameStack {
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mx_InviteDialog_roomTile_name {
|
||||
font-weight: 600;
|
||||
font-size: $font-14px;
|
||||
color: $primary-content;
|
||||
margin-left: 7px;
|
||||
}
|
||||
|
||||
.mx_InviteDialog_roomTile_userId {
|
||||
font-size: $font-12px;
|
||||
color: $muted-fg-color;
|
||||
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;
|
||||
color: $muted-fg-color;
|
||||
float: right;
|
||||
line-height: $font-36px; // Height of the avatar to keep the time vertically aligned
|
||||
}
|
||||
|
||||
.mx_InviteDialog_roomTile_highlight {
|
||||
font-weight: 900;
|
||||
}
|
||||
}
|
||||
|
||||
// Many of these styles are stolen from mx_UserPill, but adjusted for the invite dialog.
|
||||
.mx_InviteDialog_userTile {
|
||||
margin-right: 8px;
|
||||
@ -414,6 +326,125 @@ limitations under the License.
|
||||
mask-image: url('$(res)/img/voip/tab-dialpad.svg');
|
||||
}
|
||||
|
||||
.mx_InviteDialog_tile {
|
||||
cursor: pointer;
|
||||
display: grid;
|
||||
gap: $spacing-8 $spacing-12;
|
||||
align-items: center;
|
||||
|
||||
&.mx_InviteDialog_tile--room {
|
||||
grid-template-columns: min-content auto auto; // mx_InviteDialog_tile_avatarStack, mx_InviteDialog_tile_nameStack, time
|
||||
padding: $spacing-4 $spacing-8;
|
||||
|
||||
&:hover {
|
||||
background-color: $header-panel-bg-color;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.mx_InviteDialog_tile--room_selected {
|
||||
border-radius: 36px;
|
||||
background-color: $username-variant1-color;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
grid-column: 1;
|
||||
grid-row: 1;
|
||||
mask-image: url("$(res)/img/feather-customised/check.svg");
|
||||
mask-size: 100%;
|
||||
mask-repeat: no-repeat;
|
||||
position: absolute;
|
||||
top: 6px; // 50%
|
||||
left: 6px; // 50%
|
||||
background-color: #ffffff; // this is fine without a var because it's for both themes
|
||||
}
|
||||
}
|
||||
|
||||
.mx_InviteDialog_tile--room_time {
|
||||
margin-inline-start: auto;
|
||||
width: max-content;
|
||||
font-size: $font-12px;
|
||||
color: $muted-fg-color;
|
||||
}
|
||||
|
||||
.mx_InviteDialog_tile--room_highlight {
|
||||
font-weight: 900;
|
||||
}
|
||||
}
|
||||
|
||||
&.mx_InviteDialog_tile--inviterError {
|
||||
grid-template-columns: max-content auto; // max-content = avatar width
|
||||
margin-bottom: $spacing-24;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.mx_InviteDialog_tile--inviterError_errorText {
|
||||
grid-row-start: 2;
|
||||
grid-column-start: 2;
|
||||
|
||||
font-size: $font-15px;
|
||||
color: $alert;
|
||||
}
|
||||
}
|
||||
|
||||
* {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.mx_InviteDialog_tile_avatarStack,
|
||||
.mx_InviteDialog_tile--room_selected {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mx_InviteDialog_tile_avatarStack {
|
||||
grid-row-start: 1;
|
||||
grid-column-start: 1;
|
||||
|
||||
& > * {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_InviteDialog_tile_nameStack {
|
||||
grid-row-start: 1;
|
||||
grid-column-start: 2;
|
||||
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
align-self: center;
|
||||
align-items: baseline;
|
||||
gap: 2px 0;
|
||||
overflow: hidden;
|
||||
|
||||
.mx_InviteDialog_tile_nameStack_name,
|
||||
.mx_InviteDialog_tile_nameStack_userId {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.mx_InviteDialog_tile_nameStack_name {
|
||||
font-size: $font-15px;
|
||||
font-weight: $font-semi-bold;
|
||||
color: $primary-content;
|
||||
}
|
||||
|
||||
.mx_InviteDialog_tile_nameStack_userId {
|
||||
font-size: $font-12px;
|
||||
color: $muted-fg-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_InviteDialog_multiInviterError {
|
||||
> h4 {
|
||||
font-size: $font-15px;
|
||||
@ -421,36 +452,6 @@ limitations under the License.
|
||||
color: $secondary-content;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
> div {
|
||||
.mx_InviteDialog_multiInviterError_entry {
|
||||
margin-bottom: 24px;
|
||||
|
||||
.mx_InviteDialog_multiInviterError_entry_userProfile {
|
||||
.mx_InviteDialog_multiInviterError_entry_name {
|
||||
margin-left: 6px;
|
||||
font-size: $font-15px;
|
||||
line-height: $font-24px;
|
||||
font-weight: $font-semi-bold;
|
||||
color: $primary-content;
|
||||
}
|
||||
|
||||
.mx_InviteDialog_multiInviterError_entry_userId {
|
||||
margin-left: 6px;
|
||||
font-size: $font-12px;
|
||||
line-height: $font-15px;
|
||||
color: $tertiary-content;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_InviteDialog_multiInviterError_entry_error {
|
||||
margin-left: 32px;
|
||||
font-size: $font-15px;
|
||||
line-height: $font-24px;
|
||||
color: $alert;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_InviteDialog_identityServer {
|
||||
|
@ -153,19 +153,21 @@ export function showAnyInviteErrors(
|
||||
const user = userMap?.get(addr) || cli.getUser(addr);
|
||||
const name = (user as Member).name || (user as User).rawDisplayName;
|
||||
const avatarUrl = (user as Member).getMxcAvatarUrl?.() || (user as User).avatarUrl;
|
||||
return <div key={addr} className="mx_InviteDialog_multiInviterError_entry">
|
||||
<div className="mx_InviteDialog_multiInviterError_entry_userProfile">
|
||||
return <div key={addr} className="mx_InviteDialog_tile mx_InviteDialog_tile--inviterError">
|
||||
<div className="mx_InviteDialog_tile_avatarStack">
|
||||
<BaseAvatar
|
||||
url={avatarUrl ? mediaFromMxc(avatarUrl).getSquareThumbnailHttp(24) : null}
|
||||
name={name}
|
||||
idName={user.userId}
|
||||
width={24}
|
||||
height={24}
|
||||
width={36}
|
||||
height={36}
|
||||
/>
|
||||
<span className="mx_InviteDialog_multiInviterError_entry_name">{ name }</span>
|
||||
<span className="mx_InviteDialog_multiInviterError_entry_userId">{ user.userId }</span>
|
||||
</div>
|
||||
<div className="mx_InviteDialog_multiInviterError_entry_error">
|
||||
<div className="mx_InviteDialog_tile_nameStack">
|
||||
<span className="mx_InviteDialog_tile_nameStack_name">{ name }</span>
|
||||
<span className="mx_InviteDialog_tile_nameStack_userId">{ user.userId }</span>
|
||||
</div>
|
||||
<div className="mx_InviteDialog_tile--inviterError_errorText">
|
||||
{ inviter.getErrorText(addr) }
|
||||
</div>
|
||||
</div>;
|
||||
|
@ -178,7 +178,7 @@ class DMRoomTile extends React.PureComponent<IDMRoomTileProps> {
|
||||
|
||||
// Highlight the word the user entered
|
||||
const substr = str.substring(i, filterStr.length + i);
|
||||
result.push(<span className='mx_InviteDialog_roomTile_highlight' key={i + 'bold'}>{ substr }</span>);
|
||||
result.push(<span className='mx_InviteDialog_tile--room_highlight' key={i + 'bold'}>{ substr }</span>);
|
||||
i += substr.length;
|
||||
}
|
||||
|
||||
@ -194,7 +194,7 @@ class DMRoomTile extends React.PureComponent<IDMRoomTileProps> {
|
||||
let timestamp = null;
|
||||
if (this.props.lastActiveTs) {
|
||||
const humanTs = humanizeTime(this.props.lastActiveTs);
|
||||
timestamp = <span className='mx_InviteDialog_roomTile_time'>{ humanTs }</span>;
|
||||
timestamp = <span className='mx_InviteDialog_tile--room_time'>{ humanTs }</span>;
|
||||
}
|
||||
|
||||
const avatarSize = 36;
|
||||
@ -216,13 +216,13 @@ class DMRoomTile extends React.PureComponent<IDMRoomTileProps> {
|
||||
let checkmark = null;
|
||||
if (this.props.isSelected) {
|
||||
// To reduce flickering we put the 'selected' room tile above the real avatar
|
||||
checkmark = <div className='mx_InviteDialog_roomTile_selected' />;
|
||||
checkmark = <div className='mx_InviteDialog_tile--room_selected' />;
|
||||
}
|
||||
|
||||
// To reduce flickering we put the checkmark on top of the actual avatar (prevents
|
||||
// the browser from reloading the image source when the avatar remounts).
|
||||
const stackedAvatar = (
|
||||
<span className='mx_InviteDialog_roomTile_avatarStack'>
|
||||
<span className='mx_InviteDialog_tile_avatarStack'>
|
||||
{ avatar }
|
||||
{ checkmark }
|
||||
</span>
|
||||
@ -237,11 +237,11 @@ class DMRoomTile extends React.PureComponent<IDMRoomTileProps> {
|
||||
: this.highlightName(userIdentifier);
|
||||
|
||||
return (
|
||||
<div className='mx_InviteDialog_roomTile' onClick={this.onClick}>
|
||||
<div className='mx_InviteDialog_tile mx_InviteDialog_tile--room' onClick={this.onClick}>
|
||||
{ stackedAvatar }
|
||||
<span className="mx_InviteDialog_roomTile_nameStack">
|
||||
<div className='mx_InviteDialog_roomTile_name'>{ this.highlightName(this.props.member.name) }</div>
|
||||
<div className='mx_InviteDialog_roomTile_userId'>{ caption }</div>
|
||||
<span className="mx_InviteDialog_tile_nameStack">
|
||||
<div className='mx_InviteDialog_tile_nameStack_name'>{ this.highlightName(this.props.member.name) }</div>
|
||||
<div className='mx_InviteDialog_tile_nameStack_userId'>{ caption }</div>
|
||||
</span>
|
||||
{ timestamp }
|
||||
</div>
|
||||
|
@ -68,7 +68,7 @@ export async function createDm(session: ElementSession, invitees: string[]): Pro
|
||||
await session.replaceInputText(inviteesEditor, target);
|
||||
await session.delay(1000); // give it a moment to figure out a suggestion
|
||||
// find the suggestion and accept it
|
||||
const suggestions = await session.queryAll('.mx_InviteDialog_roomTile_userId');
|
||||
const suggestions = await session.queryAll('.mx_InviteDialog_tile_nameStack_userId');
|
||||
const suggestionTexts = await Promise.all(suggestions.map(s => session.innerText(s)));
|
||||
const suggestionIndex = suggestionTexts.indexOf(target);
|
||||
if (suggestionIndex === -1) {
|
||||
|
@ -35,7 +35,7 @@ export async function invite(session: ElementSession, userId: string): Promise<v
|
||||
await inviteButton.click();
|
||||
const inviteTextArea = await session.query(".mx_InviteDialog_editor input");
|
||||
await inviteTextArea.type(userId);
|
||||
const selectUserItem = await session.query(".mx_InviteDialog_roomTile");
|
||||
const selectUserItem = await session.query(".mx_InviteDialog_tile--room");
|
||||
await selectUserItem.click();
|
||||
const confirmButton = await session.query(".mx_InviteDialog_goButton");
|
||||
await confirmButton.click();
|
||||
|
Loading…
Reference in New Issue
Block a user