Merge pull request #4531 from JorikSchellekens/joriks/irc-ui
IRC ui layout
This commit is contained in:
commit
5a1bf03053
14 changed files with 615 additions and 111 deletions
|
@ -162,6 +162,8 @@
|
||||||
@import "./views/rooms/_EditMessageComposer.scss";
|
@import "./views/rooms/_EditMessageComposer.scss";
|
||||||
@import "./views/rooms/_EntityTile.scss";
|
@import "./views/rooms/_EntityTile.scss";
|
||||||
@import "./views/rooms/_EventTile.scss";
|
@import "./views/rooms/_EventTile.scss";
|
||||||
|
@import "./views/rooms/_GroupLayout.scss";
|
||||||
|
@import "./views/rooms/_IRCLayout.scss";
|
||||||
@import "./views/rooms/_InviteOnlyIcon.scss";
|
@import "./views/rooms/_InviteOnlyIcon.scss";
|
||||||
@import "./views/rooms/_JumpToBottomButton.scss";
|
@import "./views/rooms/_JumpToBottomButton.scss";
|
||||||
@import "./views/rooms/_LinkPreviewWidget.scss";
|
@import "./views/rooms/_LinkPreviewWidget.scss";
|
||||||
|
|
|
@ -37,7 +37,6 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_EventTile_avatar {
|
.mx_EventTile_avatar {
|
||||||
position: absolute;
|
|
||||||
top: 14px;
|
top: 14px;
|
||||||
left: 8px;
|
left: 8px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
@ -68,11 +67,9 @@ limitations under the License.
|
||||||
display: inline-block; /* anti-zalgo, with overflow hidden */
|
display: inline-block; /* anti-zalgo, with overflow hidden */
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding-left: 65px; /* left gutter */
|
|
||||||
padding-bottom: 0px;
|
padding-bottom: 0px;
|
||||||
padding-top: 0px;
|
padding-top: 0px;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
line-height: $font-17px;
|
|
||||||
/* the next three lines, along with overflow hidden, truncate long display names */
|
/* the next three lines, along with overflow hidden, truncate long display names */
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
@ -101,12 +98,9 @@ limitations under the License.
|
||||||
|
|
||||||
.mx_EventTile .mx_MessageTimestamp {
|
.mx_EventTile .mx_MessageTimestamp {
|
||||||
display: block;
|
display: block;
|
||||||
visibility: hidden;
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
left: 0px;
|
left: 0px;
|
||||||
width: 46px; /* 8 + 30 (avatar) + 8 */
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
position: absolute;
|
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,10 +111,7 @@ limitations under the License.
|
||||||
.mx_EventTile_line, .mx_EventTile_reply {
|
.mx_EventTile_line, .mx_EventTile_reply {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding-left: 65px; /* left gutter */
|
padding-left: 65px; /* left gutter */
|
||||||
padding-top: 3px;
|
|
||||||
padding-bottom: 3px;
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
line-height: $font-22px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomView_timeline_rr_enabled,
|
.mx_RoomView_timeline_rr_enabled,
|
||||||
|
@ -151,10 +142,6 @@ limitations under the License.
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_EventTile_info .mx_EventTile_line {
|
|
||||||
padding-left: 83px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* HACK to override line-height which is already marked important elsewhere */
|
/* HACK to override line-height which is already marked important elsewhere */
|
||||||
.mx_EventTile_bigEmoji.mx_EventTile_bigEmoji {
|
.mx_EventTile_bigEmoji.mx_EventTile_bigEmoji {
|
||||||
font-size: 48px !important;
|
font-size: 48px !important;
|
||||||
|
@ -560,84 +547,6 @@ limitations under the License.
|
||||||
|
|
||||||
/* end of overrides */
|
/* end of overrides */
|
||||||
|
|
||||||
.mx_MatrixChat_useCompactLayout {
|
|
||||||
.mx_EventTile {
|
|
||||||
padding-top: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_EventTile.mx_EventTile_info {
|
|
||||||
// same as the padding for non-compact .mx_EventTile.mx_EventTile_info
|
|
||||||
padding-top: 0px;
|
|
||||||
font-size: $font-13px;
|
|
||||||
.mx_EventTile_line, .mx_EventTile_reply {
|
|
||||||
line-height: $font-20px;
|
|
||||||
}
|
|
||||||
.mx_EventTile_avatar {
|
|
||||||
top: 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_EventTile .mx_SenderProfile {
|
|
||||||
font-size: $font-13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_EventTile.mx_EventTile_emote {
|
|
||||||
// add a bit more space for emotes so that avatars don't collide
|
|
||||||
padding-top: 8px;
|
|
||||||
.mx_EventTile_avatar {
|
|
||||||
top: 2px;
|
|
||||||
}
|
|
||||||
.mx_EventTile_line, .mx_EventTile_reply {
|
|
||||||
padding-top: 0px;
|
|
||||||
padding-bottom: 1px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_EventTile.mx_EventTile_emote.mx_EventTile_continuation {
|
|
||||||
padding-top: 0;
|
|
||||||
.mx_EventTile_line, .mx_EventTile_reply {
|
|
||||||
padding-top: 0px;
|
|
||||||
padding-bottom: 0px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_EventTile_line, .mx_EventTile_reply {
|
|
||||||
padding-top: 0px;
|
|
||||||
padding-bottom: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_EventTile_avatar {
|
|
||||||
top: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_EventTile_e2eIcon {
|
|
||||||
top: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_EventTile_readAvatars {
|
|
||||||
top: 27px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_EventTile_continuation .mx_EventTile_readAvatars,
|
|
||||||
.mx_EventTile_emote .mx_EventTile_readAvatars {
|
|
||||||
top: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_EventTile_info .mx_EventTile_readAvatars {
|
|
||||||
top: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_RoomView_MessageList h2 {
|
|
||||||
margin-top: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_EventTile_content .markdown-body {
|
|
||||||
p, ul, ol, dl, blockquote, pre, table {
|
|
||||||
margin-bottom: 4px; // 1/4 of the non-compact margin-bottom
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_EventTile_tileError {
|
.mx_EventTile_tileError {
|
||||||
color: red;
|
color: red;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
132
res/css/views/rooms/_GroupLayout.scss
Normal file
132
res/css/views/rooms/_GroupLayout.scss
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
/*
|
||||||
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
|
Copyright 2020 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
$left-gutter: 65px;
|
||||||
|
|
||||||
|
.mx_GroupLayout {
|
||||||
|
|
||||||
|
.mx_EventTile {
|
||||||
|
> .mx_SenderProfile {
|
||||||
|
line-height: $font-17px;
|
||||||
|
padding-left: $left-gutter;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .mx_EventTile_line {
|
||||||
|
padding-left: $left-gutter;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .mx_EventTile_avatar {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_MessageTimestamp {
|
||||||
|
visibility: hidden;
|
||||||
|
position: absolute;
|
||||||
|
width: 46px; /* 8 + 30 (avatar) + 8 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_EventTile_line, .mx_EventTile_reply {
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
line-height: $font-22px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_EventTile_info .mx_EventTile_line {
|
||||||
|
padding-left: calc($left-gutter + 18px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compact layout overrides */
|
||||||
|
|
||||||
|
.mx_MatrixChat_useCompactLayout {
|
||||||
|
.mx_EventTile {
|
||||||
|
padding-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_EventTile.mx_EventTile_info {
|
||||||
|
// same as the padding for non-compact .mx_EventTile.mx_EventTile_info
|
||||||
|
padding-top: 0px;
|
||||||
|
font-size: $font-13px;
|
||||||
|
.mx_EventTile_line, .mx_EventTile_reply {
|
||||||
|
line-height: $font-20px;
|
||||||
|
}
|
||||||
|
.mx_EventTile_avatar {
|
||||||
|
top: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_EventTile .mx_SenderProfile {
|
||||||
|
font-size: $font-13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_EventTile.mx_EventTile_emote {
|
||||||
|
// add a bit more space for emotes so that avatars don't collide
|
||||||
|
padding-top: 8px;
|
||||||
|
.mx_EventTile_avatar {
|
||||||
|
top: 2px;
|
||||||
|
}
|
||||||
|
.mx_EventTile_line, .mx_EventTile_reply {
|
||||||
|
padding-top: 0px;
|
||||||
|
padding-bottom: 1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_EventTile.mx_EventTile_emote.mx_EventTile_continuation {
|
||||||
|
padding-top: 0;
|
||||||
|
.mx_EventTile_line, .mx_EventTile_reply {
|
||||||
|
padding-top: 0px;
|
||||||
|
padding-bottom: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_EventTile_line, .mx_EventTile_reply {
|
||||||
|
padding-top: 0px;
|
||||||
|
padding-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_EventTile_avatar {
|
||||||
|
top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_EventTile_e2eIcon {
|
||||||
|
top: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_EventTile_readAvatars {
|
||||||
|
top: 27px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_EventTile_continuation .mx_EventTile_readAvatars,
|
||||||
|
.mx_EventTile_emote .mx_EventTile_readAvatars {
|
||||||
|
top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_EventTile_info .mx_EventTile_readAvatars {
|
||||||
|
top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_RoomView_MessageList h2 {
|
||||||
|
margin-top: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_EventTile_content .markdown-body {
|
||||||
|
p, ul, ol, dl, blockquote, pre, table {
|
||||||
|
margin-bottom: 4px; // 1/4 of the non-compact margin-bottom
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
214
res/css/views/rooms/_IRCLayout.scss
Normal file
214
res/css/views/rooms/_IRCLayout.scss
Normal file
|
@ -0,0 +1,214 @@
|
||||||
|
/*
|
||||||
|
Copyright 2020 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
$icon-width: 14px;
|
||||||
|
$timestamp-width: 45px;
|
||||||
|
$right-padding: 5px;
|
||||||
|
$irc-line-height: $font-18px;
|
||||||
|
|
||||||
|
.mx_IRCLayout {
|
||||||
|
--name-width: 70px;
|
||||||
|
|
||||||
|
line-height: $irc-line-height !important;
|
||||||
|
|
||||||
|
.mx_EventTile {
|
||||||
|
|
||||||
|
// timestamps are links which shouldn't be underlined
|
||||||
|
> a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: flex-start;
|
||||||
|
padding-top: 0;
|
||||||
|
|
||||||
|
> * {
|
||||||
|
margin-right: $right-padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .mx_EventTile_msgOption {
|
||||||
|
order: 4;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .mx_SenderProfile {
|
||||||
|
order: 2;
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: var(--name-width);
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
text-align: right;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
overflow: visible;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_EventTile_line, .mx_EventTile_reply {
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
order: 3;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .mx_EventTile_avatar {
|
||||||
|
order: 1;
|
||||||
|
position: relative;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
height: $irc-line-height;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
// Need to use important to override the js provided height and width values.
|
||||||
|
> .mx_BaseAvatar, .mx_BaseAvatar > * {
|
||||||
|
height: $font-14px !important;
|
||||||
|
width: $font-14px !important;
|
||||||
|
font-size: $font-10px !important;
|
||||||
|
line-height: $font-15px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_MessageTimestamp {
|
||||||
|
font-size: $font-10px;
|
||||||
|
width: $timestamp-width;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_EventTile_e2eIcon {
|
||||||
|
position: relative;
|
||||||
|
right: unset;
|
||||||
|
left: unset;
|
||||||
|
top: -2px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_EventTile_line {
|
||||||
|
.mx_EventTile_e2eIcon,
|
||||||
|
.mx_TextualEvent,
|
||||||
|
.mx_MTextBody,
|
||||||
|
.mx_ReplyThread_wrapper_empty {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_EvenTile_line .mx_MessageActionBar,
|
||||||
|
.mx_EvenTile_line .mx_ReplyThread_wrapper {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_EventTile_reply {
|
||||||
|
order: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_EditMessageComposer_buttons {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_EventTile_emote {
|
||||||
|
> .mx_EventTile_avatar {
|
||||||
|
margin-left: calc(var(--name-width) + $icon-width + $right-padding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_EventListSummary {
|
||||||
|
> .mx_EventTile_line {
|
||||||
|
padding-left: calc(var(--name-width) + $icon-width + $timestamp-width + 3 * $right-padding); // 15 px of padding
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_EventListSummary_avatars {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0 9px 0 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_EventTile.mx_EventTile_info {
|
||||||
|
.mx_EventTile_avatar {
|
||||||
|
left: calc(var(--name-width) + 10px + $icon-width);
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_EventTile_line {
|
||||||
|
left: calc(var(--name-width) + 10px + $icon-width);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_TextualEvent {
|
||||||
|
line-height: $irc-line-height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Suppress highlight thing from the normal Layout.
|
||||||
|
.mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_line,
|
||||||
|
.mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_line,
|
||||||
|
.mx_EventTile:hover.mx_EventTile_unknown .mx_EventTile_line {
|
||||||
|
padding-left: 0;
|
||||||
|
border-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_SenderProfile_hover {
|
||||||
|
background-color: $primary-bg-color;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
> span {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
> .mx_SenderProfile_name {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_SenderProfile:hover {
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_SenderProfile_hover:hover {
|
||||||
|
overflow: visible;
|
||||||
|
width: max(auto, 100%);
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_ReplyThread {
|
||||||
|
margin: 0;
|
||||||
|
.mx_SenderProfile {
|
||||||
|
width: unset;
|
||||||
|
max-width: var(--name-width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_ProfileResizer {
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
width: 15px;
|
||||||
|
left: calc(80px + var(--name-width));
|
||||||
|
cursor: col-resize;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Need to use important to override the js provided height and width values.
|
||||||
|
.mx_Flair > img {
|
||||||
|
height: $font-14px !important;
|
||||||
|
width: $font-14px !important;
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,6 +29,7 @@ import SettingsStore from '../../settings/SettingsStore';
|
||||||
import {_t} from "../../languageHandler";
|
import {_t} from "../../languageHandler";
|
||||||
import {haveTileForEvent} from "../views/rooms/EventTile";
|
import {haveTileForEvent} from "../views/rooms/EventTile";
|
||||||
import {textForEvent} from "../../TextForEvent";
|
import {textForEvent} from "../../TextForEvent";
|
||||||
|
import IRCTimelineProfileResizer from "../views/elements/IRCTimelineProfileResizer";
|
||||||
|
|
||||||
const CONTINUATION_MAX_INTERVAL = 5 * 60 * 1000; // 5 minutes
|
const CONTINUATION_MAX_INTERVAL = 5 * 60 * 1000; // 5 minutes
|
||||||
const continuedTypes = ['m.sticker', 'm.room.message'];
|
const continuedTypes = ['m.sticker', 'm.room.message'];
|
||||||
|
@ -109,14 +110,16 @@ export default class MessagePanel extends React.Component {
|
||||||
showReactions: PropTypes.bool,
|
showReactions: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor() {
|
// Force props to be loaded for useIRCLayout
|
||||||
super();
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
// previous positions the read marker has been in, so we can
|
// previous positions the read marker has been in, so we can
|
||||||
// display 'ghost' read markers that are animating away
|
// display 'ghost' read markers that are animating away
|
||||||
ghostReadMarkers: [],
|
ghostReadMarkers: [],
|
||||||
showTypingNotifications: SettingsStore.getValue("showTypingNotifications"),
|
showTypingNotifications: SettingsStore.getValue("showTypingNotifications"),
|
||||||
|
useIRCLayout: this.useIRCLayout(SettingsStore.getValue("feature_irc_ui")),
|
||||||
};
|
};
|
||||||
|
|
||||||
// opaque readreceipt info for each userId; used by ReadReceiptMarker
|
// opaque readreceipt info for each userId; used by ReadReceiptMarker
|
||||||
|
@ -169,6 +172,8 @@ export default class MessagePanel extends React.Component {
|
||||||
|
|
||||||
this._showTypingNotificationsWatcherRef =
|
this._showTypingNotificationsWatcherRef =
|
||||||
SettingsStore.watchSetting("showTypingNotifications", null, this.onShowTypingNotificationsChange);
|
SettingsStore.watchSetting("showTypingNotifications", null, this.onShowTypingNotificationsChange);
|
||||||
|
|
||||||
|
this._layoutWatcherRef = SettingsStore.watchSetting("feature_irc_ui", null, this.onLayoutChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
@ -178,6 +183,7 @@ export default class MessagePanel extends React.Component {
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
this._isMounted = false;
|
this._isMounted = false;
|
||||||
SettingsStore.unwatchSetting(this._showTypingNotificationsWatcherRef);
|
SettingsStore.unwatchSetting(this._showTypingNotificationsWatcherRef);
|
||||||
|
SettingsStore.unwatchSetting(this._layoutWatcherRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps, prevState) {
|
componentDidUpdate(prevProps, prevState) {
|
||||||
|
@ -196,6 +202,17 @@ export default class MessagePanel extends React.Component {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onLayoutChange = () => {
|
||||||
|
this.setState({
|
||||||
|
useIRCLayout: this.useIRCLayout(SettingsStore.getValue("feature_irc_ui")),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
useIRCLayout(ircLayoutSelected) {
|
||||||
|
// if room is null we are not in a normal room list
|
||||||
|
return ircLayoutSelected && this.props.room;
|
||||||
|
}
|
||||||
|
|
||||||
/* get the DOM node representing the given event */
|
/* get the DOM node representing the given event */
|
||||||
getNodeForEventId(eventId) {
|
getNodeForEventId(eventId) {
|
||||||
if (!this.eventNodes) {
|
if (!this.eventNodes) {
|
||||||
|
@ -597,6 +614,7 @@ export default class MessagePanel extends React.Component {
|
||||||
isSelectedEvent={highlight}
|
isSelectedEvent={highlight}
|
||||||
getRelationsForEvent={this.props.getRelationsForEvent}
|
getRelationsForEvent={this.props.getRelationsForEvent}
|
||||||
showReactions={this.props.showReactions}
|
showReactions={this.props.showReactions}
|
||||||
|
useIRCLayout={this.state.useIRCLayout}
|
||||||
/>
|
/>
|
||||||
</TileErrorBoundary>
|
</TileErrorBoundary>
|
||||||
</li>,
|
</li>,
|
||||||
|
@ -779,6 +797,8 @@ export default class MessagePanel extends React.Component {
|
||||||
this.props.className,
|
this.props.className,
|
||||||
{
|
{
|
||||||
"mx_MessagePanel_alwaysShowTimestamps": this.props.alwaysShowTimestamps,
|
"mx_MessagePanel_alwaysShowTimestamps": this.props.alwaysShowTimestamps,
|
||||||
|
"mx_IRCLayout": this.state.useIRCLayout,
|
||||||
|
"mx_GroupLayout": !this.state.useIRCLayout,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -792,6 +812,15 @@ export default class MessagePanel extends React.Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let ircResizer = null;
|
||||||
|
if (this.state.useIRCLayout) {
|
||||||
|
ircResizer = <IRCTimelineProfileResizer
|
||||||
|
minWidth={20}
|
||||||
|
maxWidth={600}
|
||||||
|
roomId={this.props.room ? this.props.roomroomId : null}
|
||||||
|
/>;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ErrorBoundary>
|
<ErrorBoundary>
|
||||||
<ScrollPanel
|
<ScrollPanel
|
||||||
|
@ -804,6 +833,7 @@ export default class MessagePanel extends React.Component {
|
||||||
style={style}
|
style={style}
|
||||||
stickyBottom={this.props.stickyBottom}
|
stickyBottom={this.props.stickyBottom}
|
||||||
resizeNotifier={this.props.resizeNotifier}
|
resizeNotifier={this.props.resizeNotifier}
|
||||||
|
fixedChildren={ircResizer}
|
||||||
>
|
>
|
||||||
{ topSpinner }
|
{ topSpinner }
|
||||||
{ this._getEventTiles() }
|
{ this._getEventTiles() }
|
||||||
|
|
|
@ -144,6 +144,11 @@ export default createReactClass({
|
||||||
/* resizeNotifier: ResizeNotifier to know when middle column has changed size
|
/* resizeNotifier: ResizeNotifier to know when middle column has changed size
|
||||||
*/
|
*/
|
||||||
resizeNotifier: PropTypes.object,
|
resizeNotifier: PropTypes.object,
|
||||||
|
|
||||||
|
/* fixedChildren: allows for children to be passed which are rendered outside
|
||||||
|
* of the wrapper
|
||||||
|
*/
|
||||||
|
fixedChildren: PropTypes.node,
|
||||||
},
|
},
|
||||||
|
|
||||||
getDefaultProps: function() {
|
getDefaultProps: function() {
|
||||||
|
@ -881,6 +886,7 @@ export default createReactClass({
|
||||||
return (<AutoHideScrollbar wrappedRef={this._collectScroll}
|
return (<AutoHideScrollbar wrappedRef={this._collectScroll}
|
||||||
onScroll={this.onScroll}
|
onScroll={this.onScroll}
|
||||||
className={`mx_ScrollPanel ${this.props.className}`} style={this.props.style}>
|
className={`mx_ScrollPanel ${this.props.className}`} style={this.props.style}>
|
||||||
|
{ this.props.fixedChildren }
|
||||||
<div className="mx_RoomView_messageListWrapper">
|
<div className="mx_RoomView_messageListWrapper">
|
||||||
<ol ref={this._itemlist} className="mx_RoomView_MessageList" aria-live="polite" role="list">
|
<ol ref={this._itemlist} className="mx_RoomView_MessageList" aria-live="polite" role="list">
|
||||||
{ this.props.children }
|
{ this.props.children }
|
||||||
|
|
84
src/components/views/elements/Draggable.tsx
Normal file
84
src/components/views/elements/Draggable.tsx
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
Copyright 2020 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 React from 'react';
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
className: string,
|
||||||
|
dragFunc: (currentLocation: ILocationState, event: MouseEvent) => ILocationState,
|
||||||
|
onMouseUp: (event: MouseEvent) => void,
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IState {
|
||||||
|
onMouseMove: (event: MouseEvent) => void,
|
||||||
|
onMouseUp: (event: MouseEvent) => void,
|
||||||
|
location: ILocationState,
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ILocationState {
|
||||||
|
currentX: number,
|
||||||
|
currentY: number,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class Draggable extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
|
constructor(props: IProps) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
onMouseMove: this.onMouseMove.bind(this),
|
||||||
|
onMouseUp: this.onMouseUp.bind(this),
|
||||||
|
location: {
|
||||||
|
currentX: 0,
|
||||||
|
currentY: 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private onMouseDown = (event: MouseEvent): void => {
|
||||||
|
this.setState({
|
||||||
|
location: {
|
||||||
|
currentX: event.clientX,
|
||||||
|
currentY: event.clientY,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener("mousemove", this.state.onMouseMove);
|
||||||
|
document.addEventListener("mouseup", this.state.onMouseUp);
|
||||||
|
console.log("Mouse down")
|
||||||
|
}
|
||||||
|
|
||||||
|
private onMouseUp = (event: MouseEvent): void => {
|
||||||
|
document.removeEventListener("mousemove", this.state.onMouseMove);
|
||||||
|
document.removeEventListener("mouseup", this.state.onMouseUp);
|
||||||
|
this.props.onMouseUp(event);
|
||||||
|
console.log("Mouse up")
|
||||||
|
}
|
||||||
|
|
||||||
|
private onMouseMove(event: MouseEvent): void {
|
||||||
|
console.log("Mouse Move")
|
||||||
|
const newLocation = this.props.dragFunc(this.state.location, event);
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
location: newLocation,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return <div className={this.props.className} onMouseDown={this.onMouseDown.bind(this)} />
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
88
src/components/views/elements/IRCTimelineProfileResizer.tsx
Normal file
88
src/components/views/elements/IRCTimelineProfileResizer.tsx
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
Copyright 2020 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 React from 'react';
|
||||||
|
import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
|
||||||
|
import Draggable, {ILocationState} from './Draggable';
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
// Current room
|
||||||
|
roomId: string,
|
||||||
|
minWidth: number,
|
||||||
|
maxWidth: number,
|
||||||
|
};
|
||||||
|
|
||||||
|
interface IState {
|
||||||
|
width: number,
|
||||||
|
IRCLayoutRoot: HTMLElement,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default class IRCTimelineProfileResizer extends React.Component<IProps, IState> {
|
||||||
|
constructor(props: IProps) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
width: SettingsStore.getValue("ircDisplayNameWidth", this.props.roomId),
|
||||||
|
IRCLayoutRoot: null,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.setState({
|
||||||
|
IRCLayoutRoot: document.querySelector(".mx_IRCLayout") as HTMLElement,
|
||||||
|
}, () => this.updateCSSWidth(this.state.width))
|
||||||
|
}
|
||||||
|
|
||||||
|
private dragFunc = (location: ILocationState, event: React.MouseEvent<Element, MouseEvent>): ILocationState => {
|
||||||
|
const offset = event.clientX - location.currentX;
|
||||||
|
const newWidth = this.state.width + offset;
|
||||||
|
|
||||||
|
console.log({offset})
|
||||||
|
// If we're trying to go smaller than min width, don't.
|
||||||
|
if (newWidth < this.props.minWidth) {
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newWidth > this.props.maxWidth) {
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
width: newWidth,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.updateCSSWidth.bind(this)(newWidth);
|
||||||
|
|
||||||
|
return {
|
||||||
|
currentX: event.clientX,
|
||||||
|
currentY: location.currentY,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateCSSWidth(newWidth: number) {
|
||||||
|
this.state.IRCLayoutRoot.style.setProperty("--name-width", newWidth + "px");
|
||||||
|
}
|
||||||
|
|
||||||
|
private onMoueUp(event: MouseEvent) {
|
||||||
|
if (this.props.roomId) {
|
||||||
|
SettingsStore.setValue("ircDisplayNameWidth", this.props.roomId, SettingLevel.ROOM_DEVICE, this.state.width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return <Draggable className="mx_ProfileResizer" dragFunc={this.dragFunc.bind(this)} onMouseUp={this.onMoueUp.bind(this)}/>
|
||||||
|
}
|
||||||
|
};
|
|
@ -37,6 +37,8 @@ export default class ReplyThread extends React.Component {
|
||||||
// called when the ReplyThread contents has changed, including EventTiles thereof
|
// called when the ReplyThread contents has changed, including EventTiles thereof
|
||||||
onHeightChanged: PropTypes.func.isRequired,
|
onHeightChanged: PropTypes.func.isRequired,
|
||||||
permalinkCreator: PropTypes.instanceOf(RoomPermalinkCreator).isRequired,
|
permalinkCreator: PropTypes.instanceOf(RoomPermalinkCreator).isRequired,
|
||||||
|
// Specifies which layout to use.
|
||||||
|
useIRCLayout: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
static contextType = MatrixClientContext;
|
static contextType = MatrixClientContext;
|
||||||
|
@ -176,12 +178,17 @@ export default class ReplyThread extends React.Component {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static makeThread(parentEv, onHeightChanged, permalinkCreator, ref) {
|
static makeThread(parentEv, onHeightChanged, permalinkCreator, ref, useIRCLayout) {
|
||||||
if (!ReplyThread.getParentEventId(parentEv)) {
|
if (!ReplyThread.getParentEventId(parentEv)) {
|
||||||
return <div />;
|
return <div className="mx_ReplyThread_wrapper_empty" />;
|
||||||
}
|
}
|
||||||
return <ReplyThread parentEv={parentEv} onHeightChanged={onHeightChanged}
|
return <ReplyThread
|
||||||
ref={ref} permalinkCreator={permalinkCreator} />;
|
parentEv={parentEv}
|
||||||
|
onHeightChanged={onHeightChanged}
|
||||||
|
ref={ref}
|
||||||
|
permalinkCreator={permalinkCreator}
|
||||||
|
useIRCLayout={useIRCLayout}
|
||||||
|
/>;
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
@ -331,11 +338,13 @@ export default class ReplyThread extends React.Component {
|
||||||
onHeightChanged={this.props.onHeightChanged}
|
onHeightChanged={this.props.onHeightChanged}
|
||||||
permalinkCreator={this.props.permalinkCreator}
|
permalinkCreator={this.props.permalinkCreator}
|
||||||
isRedacted={ev.isRedacted()}
|
isRedacted={ev.isRedacted()}
|
||||||
isTwelveHour={SettingsStore.getValue("showTwelveHourTimestamps")} />
|
isTwelveHour={SettingsStore.getValue("showTwelveHourTimestamps")}
|
||||||
|
useIRCLayout={this.props.useIRCLayout}
|
||||||
|
/>
|
||||||
</blockquote>;
|
</blockquote>;
|
||||||
});
|
});
|
||||||
|
|
||||||
return <div>
|
return <div className="mx_ReplyThread_wrapper">
|
||||||
<div>{ header }</div>
|
<div>{ header }</div>
|
||||||
<div>{ evTiles }</div>
|
<div>{ evTiles }</div>
|
||||||
</div>;
|
</div>;
|
||||||
|
|
|
@ -131,7 +131,9 @@ export default createReactClass({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_SenderProfile" dir="auto" onClick={this.props.onClick}>
|
<div className="mx_SenderProfile" dir="auto" onClick={this.props.onClick}>
|
||||||
{ content }
|
<div className="mx_SenderProfile_hover">
|
||||||
|
{ content }
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -206,6 +206,9 @@ export default createReactClass({
|
||||||
|
|
||||||
// whether to show reactions for this event
|
// whether to show reactions for this event
|
||||||
showReactions: PropTypes.bool,
|
showReactions: PropTypes.bool,
|
||||||
|
|
||||||
|
// whether to use the irc layout
|
||||||
|
useIRCLayout: PropTypes.bool,
|
||||||
},
|
},
|
||||||
|
|
||||||
getDefaultProps: function() {
|
getDefaultProps: function() {
|
||||||
|
@ -695,6 +698,9 @@ export default createReactClass({
|
||||||
// joins/parts/etc
|
// joins/parts/etc
|
||||||
avatarSize = 14;
|
avatarSize = 14;
|
||||||
needsSenderProfile = false;
|
needsSenderProfile = false;
|
||||||
|
} else if (this.props.useIRCLayout) {
|
||||||
|
avatarSize = 14;
|
||||||
|
needsSenderProfile = true;
|
||||||
} else if (this.props.continuation && this.props.tileShape !== "file_grid") {
|
} else if (this.props.continuation && this.props.tileShape !== "file_grid") {
|
||||||
// no avatar or sender profile for continuation messages
|
// no avatar or sender profile for continuation messages
|
||||||
avatarSize = 0;
|
avatarSize = 0;
|
||||||
|
@ -786,6 +792,17 @@ export default createReactClass({
|
||||||
/>;
|
/>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const linkedTimestamp = <a
|
||||||
|
href={permalink}
|
||||||
|
onClick={this.onPermalinkClicked}
|
||||||
|
aria-label={formatTime(new Date(this.props.mxEvent.getTs()), this.props.isTwelveHour)}
|
||||||
|
>
|
||||||
|
{ timestamp }
|
||||||
|
</a>;
|
||||||
|
|
||||||
|
const groupTimestamp = !this.props.useIRCLayout ? linkedTimestamp : null;
|
||||||
|
const ircTimestamp = this.props.useIRCLayout ? linkedTimestamp : null;
|
||||||
|
|
||||||
switch (this.props.tileShape) {
|
switch (this.props.tileShape) {
|
||||||
case 'notif': {
|
case 'notif': {
|
||||||
const room = this.context.getRoom(this.props.mxEvent.getRoomId());
|
const room = this.context.getRoom(this.props.mxEvent.getRoomId());
|
||||||
|
@ -853,12 +870,11 @@ export default createReactClass({
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div className={classes}>
|
<div className={classes}>
|
||||||
|
{ ircTimestamp }
|
||||||
{ avatar }
|
{ avatar }
|
||||||
{ sender }
|
{ sender }
|
||||||
<div className="mx_EventTile_reply">
|
<div className="mx_EventTile_reply">
|
||||||
<a href={permalink} onClick={this.onPermalinkClicked}>
|
{ groupTimestamp }
|
||||||
{ timestamp }
|
|
||||||
</a>
|
|
||||||
{ !isBubbleMessage && this._renderE2EPadlock() }
|
{ !isBubbleMessage && this._renderE2EPadlock() }
|
||||||
{ thread }
|
{ thread }
|
||||||
<EventTileType ref={this._tile}
|
<EventTileType ref={this._tile}
|
||||||
|
@ -877,22 +893,19 @@ export default createReactClass({
|
||||||
this.props.onHeightChanged,
|
this.props.onHeightChanged,
|
||||||
this.props.permalinkCreator,
|
this.props.permalinkCreator,
|
||||||
this._replyThread,
|
this._replyThread,
|
||||||
|
this.props.useIRCLayout,
|
||||||
);
|
);
|
||||||
|
|
||||||
// tab-index=-1 to allow it to be focusable but do not add tab stop for it, primarily for screen readers
|
// tab-index=-1 to allow it to be focusable but do not add tab stop for it, primarily for screen readers
|
||||||
return (
|
return (
|
||||||
<div className={classes} tabIndex={-1}>
|
<div className={classes} tabIndex={-1}>
|
||||||
|
{ ircTimestamp }
|
||||||
<div className="mx_EventTile_msgOption">
|
<div className="mx_EventTile_msgOption">
|
||||||
{ readAvatars }
|
{ readAvatars }
|
||||||
</div>
|
</div>
|
||||||
{ sender }
|
{ sender }
|
||||||
<div className="mx_EventTile_line">
|
<div className="mx_EventTile_line">
|
||||||
<a
|
{ groupTimestamp }
|
||||||
href={permalink}
|
|
||||||
onClick={this.onPermalinkClicked}
|
|
||||||
aria-label={formatTime(new Date(this.props.mxEvent.getTs()), this.props.isTwelveHour)}
|
|
||||||
>
|
|
||||||
{ timestamp }
|
|
||||||
</a>
|
|
||||||
{ !isBubbleMessage && this._renderE2EPadlock() }
|
{ !isBubbleMessage && this._renderE2EPadlock() }
|
||||||
{ thread }
|
{ thread }
|
||||||
<EventTileType ref={this._tile}
|
<EventTileType ref={this._tile}
|
||||||
|
|
|
@ -381,7 +381,7 @@ export default class MessageComposer extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_MessageComposer">
|
<div className="mx_MessageComposer mx_GroupLayout">
|
||||||
<div className="mx_MessageComposer_wrapper">
|
<div className="mx_MessageComposer_wrapper">
|
||||||
<div className="mx_MessageComposer_row">
|
<div className="mx_MessageComposer_row">
|
||||||
{ controls }
|
{ controls }
|
||||||
|
|
|
@ -407,6 +407,7 @@
|
||||||
"Multiple integration managers": "Multiple integration managers",
|
"Multiple integration managers": "Multiple integration managers",
|
||||||
"Try out new ways to ignore people (experimental)": "Try out new ways to ignore people (experimental)",
|
"Try out new ways to ignore people (experimental)": "Try out new ways to ignore people (experimental)",
|
||||||
"Support adding custom themes": "Support adding custom themes",
|
"Support adding custom themes": "Support adding custom themes",
|
||||||
|
"Use IRC layout": "Use IRC layout",
|
||||||
"Enable cross-signing to verify per-user instead of per-session": "Enable cross-signing to verify per-user instead of per-session",
|
"Enable cross-signing to verify per-user instead of per-session": "Enable cross-signing to verify per-user instead of per-session",
|
||||||
"Show info about bridges in room settings": "Show info about bridges in room settings",
|
"Show info about bridges in room settings": "Show info about bridges in room settings",
|
||||||
"Enable Emoji suggestions while typing": "Enable Emoji suggestions while typing",
|
"Enable Emoji suggestions while typing": "Enable Emoji suggestions while typing",
|
||||||
|
@ -453,6 +454,7 @@
|
||||||
"Keep recovery passphrase in memory for this session": "Keep recovery passphrase in memory for this session",
|
"Keep recovery passphrase in memory for this session": "Keep recovery passphrase in memory for this session",
|
||||||
"How fast should messages be downloaded.": "How fast should messages be downloaded.",
|
"How fast should messages be downloaded.": "How fast should messages be downloaded.",
|
||||||
"Manually verify all remote sessions": "Manually verify all remote sessions",
|
"Manually verify all remote sessions": "Manually verify all remote sessions",
|
||||||
|
"IRC display name width": "IRC display name width",
|
||||||
"Collecting app version information": "Collecting app version information",
|
"Collecting app version information": "Collecting app version information",
|
||||||
"Collecting logs": "Collecting logs",
|
"Collecting logs": "Collecting logs",
|
||||||
"Uploading report": "Uploading report",
|
"Uploading report": "Uploading report",
|
||||||
|
|
|
@ -137,6 +137,12 @@ export const SETTINGS = {
|
||||||
supportedLevels: LEVELS_FEATURE,
|
supportedLevels: LEVELS_FEATURE,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
"feature_irc_ui": {
|
||||||
|
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
|
||||||
|
displayName: _td('Use IRC layout'),
|
||||||
|
default: false,
|
||||||
|
isFeature: true,
|
||||||
|
},
|
||||||
"mjolnirRooms": {
|
"mjolnirRooms": {
|
||||||
supportedLevels: ['account'],
|
supportedLevels: ['account'],
|
||||||
default: [],
|
default: [],
|
||||||
|
@ -519,4 +525,11 @@ export const SETTINGS = {
|
||||||
MatrixClient.prototype.setCryptoTrustCrossSignedDevices, true,
|
MatrixClient.prototype.setCryptoTrustCrossSignedDevices, true,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
"ircDisplayNameWidth": {
|
||||||
|
// We specifically want to have room-device > device so that users may set a device default
|
||||||
|
// with a per-room override.
|
||||||
|
supportedLevels: ['room-device', 'device'],
|
||||||
|
displayName: _td("IRC display name width"),
|
||||||
|
default: 80,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue