Merge pull request #4217 from matrix-org/t3chguy/gemini
Remove Gemini Scrollbars
This commit is contained in:
commit
42ee157645
25 changed files with 39 additions and 417 deletions
|
@ -72,7 +72,6 @@
|
||||||
"flux": "2.1.1",
|
"flux": "2.1.1",
|
||||||
"focus-visible": "^5.0.2",
|
"focus-visible": "^5.0.2",
|
||||||
"fuse.js": "^2.2.0",
|
"fuse.js": "^2.2.0",
|
||||||
"gemini-scrollbar": "github:matrix-org/gemini-scrollbar#91e1e566",
|
|
||||||
"gfm.css": "^1.1.1",
|
"gfm.css": "^1.1.1",
|
||||||
"glob-to-regexp": "^0.4.1",
|
"glob-to-regexp": "^0.4.1",
|
||||||
"highlight.js": "^9.15.8",
|
"highlight.js": "^9.15.8",
|
||||||
|
@ -93,7 +92,6 @@
|
||||||
"react-beautiful-dnd": "^4.0.1",
|
"react-beautiful-dnd": "^4.0.1",
|
||||||
"react-dom": "^16.9.0",
|
"react-dom": "^16.9.0",
|
||||||
"react-focus-lock": "^2.2.1",
|
"react-focus-lock": "^2.2.1",
|
||||||
"react-gemini-scrollbar": "github:matrix-org/react-gemini-scrollbar#9cf17f63b7c0b0ec5f31df27da0f82f7238dc594",
|
|
||||||
"resize-observer-polyfill": "^1.5.0",
|
"resize-observer-polyfill": "^1.5.0",
|
||||||
"sanitize-html": "^1.18.4",
|
"sanitize-html": "^1.18.4",
|
||||||
"text-encoding-utf-8": "^1.0.1",
|
"text-encoding-utf-8": "^1.0.1",
|
||||||
|
|
|
@ -207,37 +207,6 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
|
||||||
transition: opacity 0.2s ease-in-out;
|
transition: opacity 0.2s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: critical hack to GeminiScrollbar to allow them to work in FF 42 and Chrome 48.
|
|
||||||
Stop the scrollbar view from pushing out the container's overall sizing, which causes
|
|
||||||
flexbox to adapt to the new size and cause the view to keep growing.
|
|
||||||
*/
|
|
||||||
.gm-scrollbar-container .gm-scroll-view {
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Expand thumbs on hoverover */
|
|
||||||
.gm-scrollbar {
|
|
||||||
border-radius: 5px !important;
|
|
||||||
}
|
|
||||||
.gm-scrollbar.-vertical {
|
|
||||||
width: 6px;
|
|
||||||
transition: width 120ms ease-out !important;
|
|
||||||
}
|
|
||||||
.gm-scrollbar.-vertical:hover,
|
|
||||||
.gm-scrollbar.-vertical:active {
|
|
||||||
width: 8px;
|
|
||||||
transition: width 120ms ease-out !important;
|
|
||||||
}
|
|
||||||
.gm-scrollbar.-horizontal {
|
|
||||||
height: 6px;
|
|
||||||
transition: height 120ms ease-out !important;
|
|
||||||
}
|
|
||||||
.gm-scrollbar.-horizontal:hover,
|
|
||||||
.gm-scrollbar.-horizontal:active {
|
|
||||||
height: 8px;
|
|
||||||
transition: height 120ms ease-out !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
// These are magic constants which are excluded from tinting, to let themes
|
// These are magic constants which are excluded from tinting, to let themes
|
||||||
// (which only have CSS, unlike skins) tell the app what their non-tinted
|
// (which only have CSS, unlike skins) tell the app what their non-tinted
|
||||||
// colourscheme is by inspecting the stylesheet DOM.
|
// colourscheme is by inspecting the stylesheet DOM.
|
||||||
|
|
|
@ -177,7 +177,6 @@
|
||||||
@import "./views/rooms/_RoomTile.scss";
|
@import "./views/rooms/_RoomTile.scss";
|
||||||
@import "./views/rooms/_RoomUpgradeWarningBar.scss";
|
@import "./views/rooms/_RoomUpgradeWarningBar.scss";
|
||||||
@import "./views/rooms/_SearchBar.scss";
|
@import "./views/rooms/_SearchBar.scss";
|
||||||
@import "./views/rooms/_SearchableEntityList.scss";
|
|
||||||
@import "./views/rooms/_SendMessageComposer.scss";
|
@import "./views/rooms/_SendMessageComposer.scss";
|
||||||
@import "./views/rooms/_Stickers.scss";
|
@import "./views/rooms/_Stickers.scss";
|
||||||
@import "./views/rooms/_TopUnreadMessagesBar.scss";
|
@import "./views/rooms/_TopUnreadMessagesBar.scss";
|
||||||
|
|
|
@ -180,10 +180,6 @@ limitations under the License.
|
||||||
line-height: 2em;
|
line-height: 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_GroupView > .mx_MainSplit {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_GroupView_body {
|
.mx_GroupView_body {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
@ -341,8 +337,8 @@ limitations under the License.
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_GroupView_body .gm-scroll-view > * {
|
.mx_GroupView_body .mx_AutoHideScrollbar_offset > * {
|
||||||
margin: 11px 50px 0px 68px;
|
margin: 11px 50px 50px 68px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_GroupView_groupDesc textarea {
|
.mx_GroupView_groupDesc textarea {
|
||||||
|
@ -370,7 +366,7 @@ limitations under the License.
|
||||||
padding: 40px 20px;
|
padding: 40px 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_GroupView .mx_MemberInfo .gm-scroll-view > :not(.mx_MemberInfo_avatar) {
|
.mx_GroupView .mx_MemberInfo .mx_AutoHideScrollbar_offset > :not(.mx_MemberInfo_avatar) {
|
||||||
padding-left: 16px;
|
padding-left: 16px;
|
||||||
padding-right: 16px;
|
padding-right: 16px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ limitations under the License.
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
// move hit area 5px to the right so it doesn't overlap with the timeline scrollbar
|
// move hit area 5px to the right so it doesn't overlap with the timeline scrollbar
|
||||||
|
|
|
@ -76,13 +76,6 @@ limitations under the License.
|
||||||
flex: 1 1 0;
|
flex: 1 1 0;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
|
||||||
/* Experimental fix for https://github.com/vector-im/vector-web/issues/947
|
|
||||||
and https://github.com/vector-im/vector-web/issues/946.
|
|
||||||
Empirically this stops the MessagePanel's width exploding outwards when
|
|
||||||
gemini is in 'prevented' mode
|
|
||||||
*/
|
|
||||||
overflow-x: auto;
|
|
||||||
|
|
||||||
/* To fix https://github.com/vector-im/riot-web/issues/3298 where Safari
|
/* To fix https://github.com/vector-im/riot-web/issues/3298 where Safari
|
||||||
needed height 100% all the way down to the HomePage. Height does not
|
needed height 100% all the way down to the HomePage. Height does not
|
||||||
have to be auto, empirically.
|
have to be auto, empirically.
|
||||||
|
|
|
@ -67,9 +67,6 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.mx_MyGroups_headerCard_header {
|
.mx_MyGroups_headerCard_header {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
|
@ -98,6 +95,11 @@ limitations under the License.
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_MyGroups_scrollable {
|
||||||
|
overflow-y: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MyGroups_placeholder {
|
.mx_MyGroups_placeholder {
|
||||||
|
|
|
@ -23,6 +23,7 @@ limitations under the License.
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_TagPanel_items_selected {
|
.mx_TagPanel_items_selected {
|
||||||
|
@ -57,6 +58,7 @@ limitations under the License.
|
||||||
|
|
||||||
.mx_TagPanel .mx_TagPanel_scroller {
|
.mx_TagPanel .mx_TagPanel_scroller {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_TagPanel .mx_TagPanel_tagTileContainer {
|
.mx_TagPanel .mx_TagPanel_tagTileContainer {
|
||||||
|
|
|
@ -14,14 +14,6 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// CSS voodoo to support a gemini-scrollbar for the contents of the dialog
|
|
||||||
.mx_Dialog_unknownDevice .mx_Dialog {
|
|
||||||
// ideally we'd shrink the height to fit when needed, but in practice this
|
|
||||||
// is a pain in the ass. plus might as well make the dialog big given how
|
|
||||||
// important it is.
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_UnknownDeviceDialog {
|
.mx_UnknownDeviceDialog {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -44,6 +36,7 @@ limitations under the License.
|
||||||
|
|
||||||
.mx_UnknownDeviceDialog .mx_Dialog_content {
|
.mx_UnknownDeviceDialog .mx_Dialog_content {
|
||||||
margin-bottom: 24px;
|
margin-bottom: 24px;
|
||||||
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_UnknownDeviceDialog_deviceList > li {
|
.mx_UnknownDeviceDialog_deviceList > li {
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2016 OpenMarket Ltd
|
|
||||||
|
|
||||||
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_SearchableEntityList {
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_SearchableEntityList_query {
|
|
||||||
font-family: $font-family;
|
|
||||||
border-radius: 3px;
|
|
||||||
border: 1px solid $input-border-color;
|
|
||||||
padding: 9px;
|
|
||||||
color: $primary-fg-color;
|
|
||||||
background-color: $primary-bg-color;
|
|
||||||
margin-left: 3px;
|
|
||||||
font-size: 15px;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
width: 189px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_SearchableEntityList_query::-moz-placeholder {
|
|
||||||
color: $primary-fg-color;
|
|
||||||
opacity: 0.5;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_SearchableEntityList_query::-webkit-input-placeholder {
|
|
||||||
color: $primary-fg-color;
|
|
||||||
opacity: 0.5;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_SearchableEntityList_listWrapper {
|
|
||||||
flex: 1;
|
|
||||||
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_SearchableEntityList_list {
|
|
||||||
display: table;
|
|
||||||
table-layout: fixed;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_SearchableEntityList_list .mx_EntityTile_chevron {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_SearchableEntityList_hrWrapper {
|
|
||||||
width: 100%;
|
|
||||||
flex: 0 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_SearchableEntityList hr {
|
|
||||||
height: 1px;
|
|
||||||
border: 0px;
|
|
||||||
color: $primary-fg-color;
|
|
||||||
background-color: $primary-fg-color;
|
|
||||||
margin-right: 15px;
|
|
||||||
margin-top: 11px;
|
|
||||||
margin-bottom: 11px;
|
|
||||||
}
|
|
|
@ -219,10 +219,6 @@ $user-tile-hover-bg-color: $header-panel-bg-color;
|
||||||
filter: invert(1);
|
filter: invert(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.gm-scrollbar .thumb {
|
|
||||||
filter: invert(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// markdown overrides:
|
// markdown overrides:
|
||||||
.mx_EventTile_content .markdown-body pre:hover {
|
.mx_EventTile_content .markdown-body pre:hover {
|
||||||
border-color: #808080 !important; // inverted due to rules below
|
border-color: #808080 !important; // inverted due to rules below
|
||||||
|
|
|
@ -23,11 +23,11 @@ import PropTypes from 'prop-types';
|
||||||
import request from 'browser-request';
|
import request from 'browser-request';
|
||||||
import { _t } from '../../languageHandler';
|
import { _t } from '../../languageHandler';
|
||||||
import sanitizeHtml from 'sanitize-html';
|
import sanitizeHtml from 'sanitize-html';
|
||||||
import * as sdk from '../../index';
|
|
||||||
import dis from '../../dispatcher';
|
import dis from '../../dispatcher';
|
||||||
import {MatrixClientPeg} from '../../MatrixClientPeg';
|
import {MatrixClientPeg} from '../../MatrixClientPeg';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import MatrixClientContext from "../../contexts/MatrixClientContext";
|
import MatrixClientContext from "../../contexts/MatrixClientContext";
|
||||||
|
import AutoHideScrollbar from "./AutoHideScrollbar";
|
||||||
|
|
||||||
export default class EmbeddedPage extends React.PureComponent {
|
export default class EmbeddedPage extends React.PureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
@ -117,10 +117,9 @@ export default class EmbeddedPage extends React.PureComponent {
|
||||||
</div>;
|
</div>;
|
||||||
|
|
||||||
if (this.props.scrollbar) {
|
if (this.props.scrollbar) {
|
||||||
const GeminiScrollbarWrapper = sdk.getComponent("elements.GeminiScrollbarWrapper");
|
return <AutoHideScrollbar className={classes}>
|
||||||
return <GeminiScrollbarWrapper autoshow={true} className={classes}>
|
|
||||||
{content}
|
{content}
|
||||||
</GeminiScrollbarWrapper>;
|
</AutoHideScrollbar>;
|
||||||
} else {
|
} else {
|
||||||
return <div className={classes}>
|
return <div className={classes}>
|
||||||
{content}
|
{content}
|
||||||
|
|
|
@ -39,6 +39,7 @@ import {makeGroupPermalink, makeUserPermalink} from "../../utils/permalinks/Perm
|
||||||
import {Group} from "matrix-js-sdk";
|
import {Group} from "matrix-js-sdk";
|
||||||
import {allSettled, sleep} from "../../utils/promise";
|
import {allSettled, sleep} from "../../utils/promise";
|
||||||
import RightPanelStore from "../../stores/RightPanelStore";
|
import RightPanelStore from "../../stores/RightPanelStore";
|
||||||
|
import AutoHideScrollbar from "./AutoHideScrollbar";
|
||||||
|
|
||||||
const LONG_DESC_PLACEHOLDER = _td(
|
const LONG_DESC_PLACEHOLDER = _td(
|
||||||
`<h1>HTML for your community's page</h1>
|
`<h1>HTML for your community's page</h1>
|
||||||
|
@ -1173,7 +1174,6 @@ export default createReactClass({
|
||||||
render: function() {
|
render: function() {
|
||||||
const GroupAvatar = sdk.getComponent("avatars.GroupAvatar");
|
const GroupAvatar = sdk.getComponent("avatars.GroupAvatar");
|
||||||
const Spinner = sdk.getComponent("elements.Spinner");
|
const Spinner = sdk.getComponent("elements.Spinner");
|
||||||
const GeminiScrollbarWrapper = sdk.getComponent("elements.GeminiScrollbarWrapper");
|
|
||||||
|
|
||||||
if (this.state.summaryLoading && this.state.error === null || this.state.saving) {
|
if (this.state.summaryLoading && this.state.error === null || this.state.saving) {
|
||||||
return <Spinner />;
|
return <Spinner />;
|
||||||
|
@ -1332,10 +1332,10 @@ export default createReactClass({
|
||||||
<GroupHeaderButtons />
|
<GroupHeaderButtons />
|
||||||
</div>
|
</div>
|
||||||
<MainSplit panel={rightPanel}>
|
<MainSplit panel={rightPanel}>
|
||||||
<GeminiScrollbarWrapper className="mx_GroupView_body">
|
<AutoHideScrollbar className="mx_GroupView_body">
|
||||||
{ this._getMembershipSection() }
|
{ this._getMembershipSection() }
|
||||||
{ this._getGroupSection() }
|
{ this._getGroupSection() }
|
||||||
</GeminiScrollbarWrapper>
|
</AutoHideScrollbar>
|
||||||
</MainSplit>
|
</MainSplit>
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
|
|
|
@ -22,6 +22,7 @@ import { _t } from '../../languageHandler';
|
||||||
import dis from '../../dispatcher';
|
import dis from '../../dispatcher';
|
||||||
import AccessibleButton from '../views/elements/AccessibleButton';
|
import AccessibleButton from '../views/elements/AccessibleButton';
|
||||||
import MatrixClientContext from "../../contexts/MatrixClientContext";
|
import MatrixClientContext from "../../contexts/MatrixClientContext";
|
||||||
|
import AutoHideScrollbar from "./AutoHideScrollbar";
|
||||||
|
|
||||||
export default createReactClass({
|
export default createReactClass({
|
||||||
displayName: 'MyGroups',
|
displayName: 'MyGroups',
|
||||||
|
@ -62,8 +63,6 @@ export default createReactClass({
|
||||||
const Loader = sdk.getComponent("elements.Spinner");
|
const Loader = sdk.getComponent("elements.Spinner");
|
||||||
const SimpleRoomHeader = sdk.getComponent('rooms.SimpleRoomHeader');
|
const SimpleRoomHeader = sdk.getComponent('rooms.SimpleRoomHeader');
|
||||||
const GroupTile = sdk.getComponent("groups.GroupTile");
|
const GroupTile = sdk.getComponent("groups.GroupTile");
|
||||||
const GeminiScrollbarWrapper = sdk.getComponent("elements.GeminiScrollbarWrapper");
|
|
||||||
|
|
||||||
|
|
||||||
let content;
|
let content;
|
||||||
let contentHeader;
|
let contentHeader;
|
||||||
|
@ -74,7 +73,7 @@ export default createReactClass({
|
||||||
});
|
});
|
||||||
contentHeader = groupNodes.length > 0 ? <h3>{ _t('Your Communities') }</h3> : <div />;
|
contentHeader = groupNodes.length > 0 ? <h3>{ _t('Your Communities') }</h3> : <div />;
|
||||||
content = groupNodes.length > 0 ?
|
content = groupNodes.length > 0 ?
|
||||||
<GeminiScrollbarWrapper>
|
<AutoHideScrollbar className="mx_MyGroups_scrollable">
|
||||||
<div className="mx_MyGroups_microcopy">
|
<div className="mx_MyGroups_microcopy">
|
||||||
<p>
|
<p>
|
||||||
{ _t(
|
{ _t(
|
||||||
|
@ -93,7 +92,7 @@ export default createReactClass({
|
||||||
<div className="mx_MyGroups_joinedGroups">
|
<div className="mx_MyGroups_joinedGroups">
|
||||||
{ groupNodes }
|
{ groupNodes }
|
||||||
</div>
|
</div>
|
||||||
</GeminiScrollbarWrapper> :
|
</AutoHideScrollbar> :
|
||||||
<div className="mx_MyGroups_placeholder">
|
<div className="mx_MyGroups_placeholder">
|
||||||
{ _t(
|
{ _t(
|
||||||
"You're not currently a member of any communities.",
|
"You're not currently a member of any communities.",
|
||||||
|
|
|
@ -405,21 +405,6 @@ export default createReactClass({
|
||||||
this.onResize();
|
this.onResize();
|
||||||
|
|
||||||
document.addEventListener("keydown", this.onKeyDown);
|
document.addEventListener("keydown", this.onKeyDown);
|
||||||
|
|
||||||
// XXX: EVIL HACK to autofocus inviting on empty rooms.
|
|
||||||
// We use the setTimeout to avoid racing with focus_composer.
|
|
||||||
if (this.state.room &&
|
|
||||||
this.state.room.getJoinedMemberCount() == 1 &&
|
|
||||||
this.state.room.getLiveTimeline() &&
|
|
||||||
this.state.room.getLiveTimeline().getEvents() &&
|
|
||||||
this.state.room.getLiveTimeline().getEvents().length <= 6) {
|
|
||||||
const inviteBox = document.getElementById("mx_SearchableEntityList_query");
|
|
||||||
setTimeout(function() {
|
|
||||||
if (inviteBox) {
|
|
||||||
inviteBox.focus();
|
|
||||||
}
|
|
||||||
}, 50);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
shouldComponentUpdate: function(nextProps, nextState) {
|
shouldComponentUpdate: function(nextProps, nextState) {
|
||||||
|
|
|
@ -782,7 +782,7 @@ export default createReactClass({
|
||||||
if (!this._divScroll) {
|
if (!this._divScroll) {
|
||||||
// Likewise, we should have the ref by this point, but if not
|
// Likewise, we should have the ref by this point, but if not
|
||||||
// turn the NPE into something meaningful.
|
// turn the NPE into something meaningful.
|
||||||
throw new Error("ScrollPanel._getScrollNode called before gemini ref collected");
|
throw new Error("ScrollPanel._getScrollNode called before AutoHideScrollbar ref collected");
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._divScroll;
|
return this._divScroll;
|
||||||
|
|
|
@ -28,6 +28,7 @@ import { _t } from '../../languageHandler';
|
||||||
import { Droppable } from 'react-beautiful-dnd';
|
import { Droppable } from 'react-beautiful-dnd';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import MatrixClientContext from "../../contexts/MatrixClientContext";
|
import MatrixClientContext from "../../contexts/MatrixClientContext";
|
||||||
|
import AutoHideScrollbar from "./AutoHideScrollbar";
|
||||||
|
|
||||||
const TagPanel = createReactClass({
|
const TagPanel = createReactClass({
|
||||||
displayName: 'TagPanel',
|
displayName: 'TagPanel',
|
||||||
|
@ -106,7 +107,6 @@ const TagPanel = createReactClass({
|
||||||
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
||||||
const ActionButton = sdk.getComponent('elements.ActionButton');
|
const ActionButton = sdk.getComponent('elements.ActionButton');
|
||||||
const TintableSvg = sdk.getComponent('elements.TintableSvg');
|
const TintableSvg = sdk.getComponent('elements.TintableSvg');
|
||||||
const GeminiScrollbarWrapper = sdk.getComponent("elements.GeminiScrollbarWrapper");
|
|
||||||
|
|
||||||
const tags = this.state.orderedTags.map((tag, index) => {
|
const tags = this.state.orderedTags.map((tag, index) => {
|
||||||
return <DNDTagTile
|
return <DNDTagTile
|
||||||
|
@ -138,9 +138,8 @@ const TagPanel = createReactClass({
|
||||||
{ clearButton }
|
{ clearButton }
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_TagPanel_divider" />
|
<div className="mx_TagPanel_divider" />
|
||||||
<GeminiScrollbarWrapper
|
<AutoHideScrollbar
|
||||||
className="mx_TagPanel_scroller"
|
className="mx_TagPanel_scroller"
|
||||||
autoshow={true}
|
|
||||||
// XXX: Use onMouseDown as a workaround for https://github.com/atlassian/react-beautiful-dnd/issues/273
|
// XXX: Use onMouseDown as a workaround for https://github.com/atlassian/react-beautiful-dnd/issues/273
|
||||||
// instead of onClick. Otherwise we experience https://github.com/vector-im/riot-web/issues/6253
|
// instead of onClick. Otherwise we experience https://github.com/vector-im/riot-web/issues/6253
|
||||||
onMouseDown={this.onMouseDown}
|
onMouseDown={this.onMouseDown}
|
||||||
|
@ -166,7 +165,7 @@ const TagPanel = createReactClass({
|
||||||
</div>
|
</div>
|
||||||
) }
|
) }
|
||||||
</Droppable>
|
</Droppable>
|
||||||
</GeminiScrollbarWrapper>
|
</AutoHideScrollbar>
|
||||||
</div>;
|
</div>;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -122,7 +122,6 @@ export default createReactClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
const GeminiScrollbarWrapper = sdk.getComponent("elements.GeminiScrollbarWrapper");
|
|
||||||
if (this.props.devices === null) {
|
if (this.props.devices === null) {
|
||||||
const Spinner = sdk.getComponent("elements.Spinner");
|
const Spinner = sdk.getComponent("elements.Spinner");
|
||||||
return <Spinner />;
|
return <Spinner />;
|
||||||
|
@ -168,7 +167,7 @@ export default createReactClass({
|
||||||
title={_t('Room contains unknown sessions')}
|
title={_t('Room contains unknown sessions')}
|
||||||
contentId='mx_Dialog_content'
|
contentId='mx_Dialog_content'
|
||||||
>
|
>
|
||||||
<GeminiScrollbarWrapper autoshow={false} className="mx_Dialog_content" id='mx_Dialog_content'>
|
<div className="mx_Dialog_content" id='mx_Dialog_content'>
|
||||||
<h4>
|
<h4>
|
||||||
{ _t('"%(RoomName)s" contains sessions that you haven\'t seen before.', {RoomName: this.props.room.name}) }
|
{ _t('"%(RoomName)s" contains sessions that you haven\'t seen before.', {RoomName: this.props.room.name}) }
|
||||||
</h4>
|
</h4>
|
||||||
|
@ -176,7 +175,7 @@ export default createReactClass({
|
||||||
{ _t("Unknown sessions") }:
|
{ _t("Unknown sessions") }:
|
||||||
|
|
||||||
<UnknownDeviceList devices={this.props.devices} />
|
<UnknownDeviceList devices={this.props.devices} />
|
||||||
</GeminiScrollbarWrapper>
|
</div>
|
||||||
<DialogButtons primaryButton={sendButtonLabel}
|
<DialogButtons primaryButton={sendButtonLabel}
|
||||||
onPrimaryButtonClick={sendButtonOnClick}
|
onPrimaryButtonClick={sendButtonOnClick}
|
||||||
onCancel={this._onDismissClicked} />
|
onCancel={this._onDismissClicked} />
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2018 New Vector Ltd.
|
|
||||||
|
|
||||||
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 GeminiScrollbar from 'react-gemini-scrollbar';
|
|
||||||
|
|
||||||
function GeminiScrollbarWrapper(props) {
|
|
||||||
const {wrappedRef, ...wrappedProps} = props;
|
|
||||||
|
|
||||||
// Enable forceGemini so that gemini is always enabled. This is
|
|
||||||
// to avoid future issues where a feature is implemented without
|
|
||||||
// doing QA on every OS/browser combination.
|
|
||||||
//
|
|
||||||
// By default GeminiScrollbar allows native scrollbars to be used
|
|
||||||
// on macOS. Use forceGemini to enable Gemini's non-native
|
|
||||||
// scrollbars on all OSs.
|
|
||||||
return <GeminiScrollbar ref={wrappedRef} forceGemini={true} {...wrappedProps}>
|
|
||||||
{ props.children }
|
|
||||||
</GeminiScrollbar>;
|
|
||||||
}
|
|
||||||
export default GeminiScrollbarWrapper;
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ import { GroupMemberType } from '../../../groups';
|
||||||
import GroupStore from '../../../stores/GroupStore';
|
import GroupStore from '../../../stores/GroupStore';
|
||||||
import AccessibleButton from '../elements/AccessibleButton';
|
import AccessibleButton from '../elements/AccessibleButton';
|
||||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||||
|
import AutoHideScrollbar from "../../structures/AutoHideScrollbar";
|
||||||
|
|
||||||
export default createReactClass({
|
export default createReactClass({
|
||||||
displayName: 'GroupMemberInfo',
|
displayName: 'GroupMemberInfo',
|
||||||
|
@ -182,10 +183,9 @@ export default createReactClass({
|
||||||
this.props.groupMember.displayname || this.props.groupMember.userId
|
this.props.groupMember.displayname || this.props.groupMember.userId
|
||||||
);
|
);
|
||||||
|
|
||||||
const GeminiScrollbarWrapper = sdk.getComponent('elements.GeminiScrollbarWrapper');
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_MemberInfo" role="tabpanel">
|
<div className="mx_MemberInfo" role="tabpanel">
|
||||||
<GeminiScrollbarWrapper autoshow={true}>
|
<AutoHideScrollbar>
|
||||||
<AccessibleButton className="mx_MemberInfo_cancel" onClick={this._onCancel}>
|
<AccessibleButton className="mx_MemberInfo_cancel" onClick={this._onCancel}>
|
||||||
<img src={require("../../../../res/img/cancel.svg")} width="18" height="18" className="mx_filterFlipColor" />
|
<img src={require("../../../../res/img/cancel.svg")} width="18" height="18" className="mx_filterFlipColor" />
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
|
@ -199,7 +199,7 @@ export default createReactClass({
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{ adminTools }
|
{ adminTools }
|
||||||
</GeminiScrollbarWrapper>
|
</AutoHideScrollbar>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -26,6 +26,7 @@ import { showGroupInviteDialog } from '../../../GroupAddressPicker';
|
||||||
import AccessibleButton from '../elements/AccessibleButton';
|
import AccessibleButton from '../elements/AccessibleButton';
|
||||||
import TintableSvg from '../elements/TintableSvg';
|
import TintableSvg from '../elements/TintableSvg';
|
||||||
import {RIGHT_PANEL_PHASES} from "../../../stores/RightPanelStorePhases";
|
import {RIGHT_PANEL_PHASES} from "../../../stores/RightPanelStorePhases";
|
||||||
|
import AutoHideScrollbar from "../../structures/AutoHideScrollbar";
|
||||||
|
|
||||||
const INITIAL_LOAD_NUM_MEMBERS = 30;
|
const INITIAL_LOAD_NUM_MEMBERS = 30;
|
||||||
|
|
||||||
|
@ -172,7 +173,6 @@ export default createReactClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
const GeminiScrollbarWrapper = sdk.getComponent("elements.GeminiScrollbarWrapper");
|
|
||||||
if (this.state.fetching || this.state.fetchingInvitedMembers) {
|
if (this.state.fetching || this.state.fetchingInvitedMembers) {
|
||||||
const Spinner = sdk.getComponent("elements.Spinner");
|
const Spinner = sdk.getComponent("elements.Spinner");
|
||||||
return (<div className="mx_MemberList">
|
return (<div className="mx_MemberList">
|
||||||
|
@ -225,10 +225,10 @@ export default createReactClass({
|
||||||
return (
|
return (
|
||||||
<div className="mx_MemberList" role="tabpanel">
|
<div className="mx_MemberList" role="tabpanel">
|
||||||
{ inviteButton }
|
{ inviteButton }
|
||||||
<GeminiScrollbarWrapper autoshow={true}>
|
<AutoHideScrollbar>
|
||||||
{ joined }
|
{ joined }
|
||||||
{ invited }
|
{ invited }
|
||||||
</GeminiScrollbarWrapper>
|
</AutoHideScrollbar>
|
||||||
{ inputBox }
|
{ inputBox }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -24,6 +24,7 @@ import * as sdk from '../../../index';
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
import GroupStore from '../../../stores/GroupStore';
|
import GroupStore from '../../../stores/GroupStore';
|
||||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||||
|
import AutoHideScrollbar from "../../structures/AutoHideScrollbar";
|
||||||
|
|
||||||
export default createReactClass({
|
export default createReactClass({
|
||||||
displayName: 'GroupRoomInfo',
|
displayName: 'GroupRoomInfo',
|
||||||
|
@ -153,7 +154,6 @@ export default createReactClass({
|
||||||
render: function() {
|
render: function() {
|
||||||
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
||||||
const InlineSpinner = sdk.getComponent('elements.InlineSpinner');
|
const InlineSpinner = sdk.getComponent('elements.InlineSpinner');
|
||||||
const GeminiScrollbarWrapper = sdk.getComponent("elements.GeminiScrollbarWrapper");
|
|
||||||
if (this.state.groupRoomRemoveLoading || !this.state.groupRoom) {
|
if (this.state.groupRoomRemoveLoading || !this.state.groupRoom) {
|
||||||
const Spinner = sdk.getComponent("elements.Spinner");
|
const Spinner = sdk.getComponent("elements.Spinner");
|
||||||
return <div className="mx_MemberInfo">
|
return <div className="mx_MemberInfo">
|
||||||
|
@ -216,7 +216,7 @@ export default createReactClass({
|
||||||
const groupRoomName = this.state.groupRoom.displayname;
|
const groupRoomName = this.state.groupRoom.displayname;
|
||||||
return (
|
return (
|
||||||
<div className="mx_MemberInfo" role="tabpanel">
|
<div className="mx_MemberInfo" role="tabpanel">
|
||||||
<GeminiScrollbarWrapper autoshow={true}>
|
<AutoHideScrollbar>
|
||||||
<AccessibleButton className="mx_MemberInfo_cancel" onClick={this._onCancel}>
|
<AccessibleButton className="mx_MemberInfo_cancel" onClick={this._onCancel}>
|
||||||
<img src={require("../../../../res/img/cancel.svg")} width="18" height="18" className="mx_filterFlipColor" />
|
<img src={require("../../../../res/img/cancel.svg")} width="18" height="18" className="mx_filterFlipColor" />
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
|
@ -231,7 +231,7 @@ export default createReactClass({
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{ adminTools }
|
{ adminTools }
|
||||||
</GeminiScrollbarWrapper>
|
</AutoHideScrollbar>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -22,6 +22,7 @@ import PropTypes from 'prop-types';
|
||||||
import { showGroupAddRoomDialog } from '../../../GroupAddressPicker';
|
import { showGroupAddRoomDialog } from '../../../GroupAddressPicker';
|
||||||
import AccessibleButton from '../elements/AccessibleButton';
|
import AccessibleButton from '../elements/AccessibleButton';
|
||||||
import TintableSvg from '../elements/TintableSvg';
|
import TintableSvg from '../elements/TintableSvg';
|
||||||
|
import AutoHideScrollbar from "../../structures/AutoHideScrollbar";
|
||||||
|
|
||||||
const INITIAL_LOAD_NUM_ROOMS = 30;
|
const INITIAL_LOAD_NUM_ROOMS = 30;
|
||||||
|
|
||||||
|
@ -150,17 +151,16 @@ export default createReactClass({
|
||||||
placeholder={_t('Filter community rooms')} autoComplete="off" />
|
placeholder={_t('Filter community rooms')} autoComplete="off" />
|
||||||
);
|
);
|
||||||
|
|
||||||
const GeminiScrollbarWrapper = sdk.getComponent("elements.GeminiScrollbarWrapper");
|
|
||||||
const TruncatedList = sdk.getComponent("elements.TruncatedList");
|
const TruncatedList = sdk.getComponent("elements.TruncatedList");
|
||||||
return (
|
return (
|
||||||
<div className="mx_GroupRoomList" role="tabpanel">
|
<div className="mx_GroupRoomList" role="tabpanel">
|
||||||
{ inviteButton }
|
{ inviteButton }
|
||||||
<GeminiScrollbarWrapper autoshow={true} className="mx_GroupRoomList_joined mx_GroupRoomList_outerWrapper">
|
<AutoHideScrollbar className="mx_GroupRoomList_joined mx_GroupRoomList_outerWrapper">
|
||||||
<TruncatedList className="mx_GroupRoomList_wrapper" truncateAt={this.state.truncateAt}
|
<TruncatedList className="mx_GroupRoomList_wrapper" truncateAt={this.state.truncateAt}
|
||||||
createOverflowElement={this._createOverflowTile}>
|
createOverflowElement={this._createOverflowTile}>
|
||||||
{ this.makeGroupRoomTiles(this.state.searchQuery) }
|
{ this.makeGroupRoomTiles(this.state.searchQuery) }
|
||||||
</TruncatedList>
|
</TruncatedList>
|
||||||
</GeminiScrollbarWrapper>
|
</AutoHideScrollbar>
|
||||||
{ inputBox }
|
{ inputBox }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,186 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2015, 2016 OpenMarket Ltd
|
|
||||||
Copyright 2019 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 PropTypes from 'prop-types';
|
|
||||||
import createReactClass from 'create-react-class';
|
|
||||||
import * as sdk from "../../../index";
|
|
||||||
import { _t } from '../../../languageHandler';
|
|
||||||
|
|
||||||
// A list capable of displaying entities which conform to the SearchableEntity
|
|
||||||
// interface which is an object containing getJsx(): Jsx and matches(query: string): boolean
|
|
||||||
const SearchableEntityList = createReactClass({
|
|
||||||
displayName: 'SearchableEntityList',
|
|
||||||
|
|
||||||
propTypes: {
|
|
||||||
emptyQueryShowsAll: PropTypes.bool,
|
|
||||||
showInputBox: PropTypes.bool,
|
|
||||||
onQueryChanged: PropTypes.func, // fn(inputText)
|
|
||||||
onSubmit: PropTypes.func, // fn(inputText)
|
|
||||||
entities: PropTypes.array,
|
|
||||||
truncateAt: PropTypes.number,
|
|
||||||
},
|
|
||||||
|
|
||||||
getDefaultProps: function() {
|
|
||||||
return {
|
|
||||||
showInputBox: true,
|
|
||||||
entities: [],
|
|
||||||
emptyQueryShowsAll: false,
|
|
||||||
onSubmit: function() {},
|
|
||||||
onQueryChanged: function(input) {},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
getInitialState: function() {
|
|
||||||
return {
|
|
||||||
query: "",
|
|
||||||
focused: false,
|
|
||||||
truncateAt: this.props.truncateAt,
|
|
||||||
results: this.getSearchResults("", this.props.entities),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
componentWillReceiveProps: function(newProps) {
|
|
||||||
// recalculate the search results in case we got new entities
|
|
||||||
this.setState({
|
|
||||||
results: this.getSearchResults(this.state.query, newProps.entities),
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
componentWillUnmount: function() {
|
|
||||||
// pretend the query box was blanked out else filters could still be
|
|
||||||
// applied to other components which rely on onQueryChanged.
|
|
||||||
this.props.onQueryChanged("");
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Public-facing method to set the input query text to the given input.
|
|
||||||
* @param {string} input
|
|
||||||
*/
|
|
||||||
setQuery: function(input) {
|
|
||||||
this.setState({
|
|
||||||
query: input,
|
|
||||||
results: this.getSearchResults(input, this.props.entities),
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
onQueryChanged: function(ev) {
|
|
||||||
const q = ev.target.value;
|
|
||||||
this.setState({
|
|
||||||
query: q,
|
|
||||||
// reset truncation if they back out the entire text
|
|
||||||
truncateAt: (q.length === 0 ? this.props.truncateAt : this.state.truncateAt),
|
|
||||||
results: this.getSearchResults(q, this.props.entities),
|
|
||||||
}, () => {
|
|
||||||
// invoke the callback AFTER we've flushed the new state. We need to
|
|
||||||
// do this because onQueryChanged can result in new props being passed
|
|
||||||
// to this component, which will then try to recalculate the search
|
|
||||||
// list. If we do this without flushing, we'll recalc with the last
|
|
||||||
// search term and not the current one!
|
|
||||||
this.props.onQueryChanged(q);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
onQuerySubmit: function(ev) {
|
|
||||||
ev.preventDefault();
|
|
||||||
this.props.onSubmit(this.state.query);
|
|
||||||
},
|
|
||||||
|
|
||||||
getSearchResults: function(query, entities) {
|
|
||||||
if (!query || query.length === 0) {
|
|
||||||
return this.props.emptyQueryShowsAll ? entities : [];
|
|
||||||
}
|
|
||||||
return entities.filter(function(e) {
|
|
||||||
return e.matches(query);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
_showAll: function() {
|
|
||||||
this.setState({
|
|
||||||
truncateAt: -1,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
_createOverflowEntity: function(overflowCount, totalCount) {
|
|
||||||
const EntityTile = sdk.getComponent("rooms.EntityTile");
|
|
||||||
const BaseAvatar = sdk.getComponent("avatars.BaseAvatar");
|
|
||||||
const text = _t("and %(count)s others...", { count: overflowCount });
|
|
||||||
return (
|
|
||||||
<EntityTile className="mx_EntityTile_ellipsis" avatarJsx={
|
|
||||||
<BaseAvatar url={require("../../../../res/img/ellipsis.svg")} name="..." width={36} height={36} />
|
|
||||||
} name={text} presenceState="online" suppressOnHover={true}
|
|
||||||
onClick={this._showAll} />
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
render: function() {
|
|
||||||
let inputBox;
|
|
||||||
|
|
||||||
if (this.props.showInputBox) {
|
|
||||||
inputBox = (
|
|
||||||
<form onSubmit={this.onQuerySubmit} autoComplete="off">
|
|
||||||
<input className="mx_SearchableEntityList_query" id="mx_SearchableEntityList_query" type="text"
|
|
||||||
onChange={this.onQueryChanged} value={this.state.query}
|
|
||||||
onFocus= {() => { this.setState({ focused: true }); }}
|
|
||||||
onBlur= {() => { this.setState({ focused: false }); }}
|
|
||||||
placeholder={_t("Search")} />
|
|
||||||
</form>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let list;
|
|
||||||
if (this.state.results.length > 1 || this.state.focused) {
|
|
||||||
if (this.props.truncateAt) { // caller wants list truncated
|
|
||||||
const TruncatedList = sdk.getComponent("elements.TruncatedList");
|
|
||||||
list = (
|
|
||||||
<TruncatedList className="mx_SearchableEntityList_list"
|
|
||||||
truncateAt={this.state.truncateAt} // use state truncation as it may be expanded
|
|
||||||
createOverflowElement={this._createOverflowEntity}>
|
|
||||||
{ this.state.results.map((entity) => {
|
|
||||||
return entity.getJsx();
|
|
||||||
}) }
|
|
||||||
</TruncatedList>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
list = (
|
|
||||||
<div className="mx_SearchableEntityList_list">
|
|
||||||
{ this.state.results.map((entity) => {
|
|
||||||
return entity.getJsx();
|
|
||||||
}) }
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
const GeminiScrollbarWrapper = sdk.getComponent("elements.GeminiScrollbarWrapper");
|
|
||||||
list = (
|
|
||||||
<GeminiScrollbarWrapper autoshow={true}
|
|
||||||
className="mx_SearchableEntityList_listWrapper">
|
|
||||||
{ list }
|
|
||||||
</GeminiScrollbarWrapper>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={"mx_SearchableEntityList " + (list ? "mx_SearchableEntityList_expanded" : "")}>
|
|
||||||
{ inputBox }
|
|
||||||
{ list }
|
|
||||||
{ list ? <div className="mx_SearchableEntityList_hrWrapper"><hr /></div> : '' }
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export default SearchableEntityList;
|
|
10
yarn.lock
10
yarn.lock
|
@ -3902,10 +3902,6 @@ fuse.js@^2.2.0:
|
||||||
resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-2.7.4.tgz#96e420fde7ef011ac49c258a621314fe576536f9"
|
resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-2.7.4.tgz#96e420fde7ef011ac49c258a621314fe576536f9"
|
||||||
integrity sha1-luQg/efvARrEnCWKYhMU/ldlNvk=
|
integrity sha1-luQg/efvARrEnCWKYhMU/ldlNvk=
|
||||||
|
|
||||||
"gemini-scrollbar@github:matrix-org/gemini-scrollbar#91e1e566", gemini-scrollbar@matrix-org/gemini-scrollbar#91e1e566:
|
|
||||||
version "1.4.3"
|
|
||||||
resolved "https://codeload.github.com/matrix-org/gemini-scrollbar/tar.gz/91e1e566fa33324188f278801baf4a79f9f554ab"
|
|
||||||
|
|
||||||
gensync@^1.0.0-beta.1:
|
gensync@^1.0.0-beta.1:
|
||||||
version "1.0.0-beta.1"
|
version "1.0.0-beta.1"
|
||||||
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269"
|
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269"
|
||||||
|
@ -6963,12 +6959,6 @@ react-focus-lock@^2.2.1:
|
||||||
use-callback-ref "^1.2.1"
|
use-callback-ref "^1.2.1"
|
||||||
use-sidecar "^1.0.1"
|
use-sidecar "^1.0.1"
|
||||||
|
|
||||||
"react-gemini-scrollbar@github:matrix-org/react-gemini-scrollbar#9cf17f63b7c0b0ec5f31df27da0f82f7238dc594":
|
|
||||||
version "2.1.5"
|
|
||||||
resolved "https://codeload.github.com/matrix-org/react-gemini-scrollbar/tar.gz/9cf17f63b7c0b0ec5f31df27da0f82f7238dc594"
|
|
||||||
dependencies:
|
|
||||||
gemini-scrollbar matrix-org/gemini-scrollbar#91e1e566
|
|
||||||
|
|
||||||
react-is@^16.12.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6, react-is@^16.9.0:
|
react-is@^16.12.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6, react-is@^16.9.0:
|
||||||
version "16.13.0"
|
version "16.13.0"
|
||||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.0.tgz#0f37c3613c34fe6b37cd7f763a0d6293ab15c527"
|
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.0.tgz#0f37c3613c34fe6b37cd7f763a0d6293ab15c527"
|
||||||
|
|
Loading…
Reference in a new issue