LeftPanel2 -> LeftPanel
parent
52219a8341
commit
2441cbc9ac
|
@ -11,7 +11,7 @@
|
||||||
@import "./structures/_GroupView.scss";
|
@import "./structures/_GroupView.scss";
|
||||||
@import "./structures/_HeaderButtons.scss";
|
@import "./structures/_HeaderButtons.scss";
|
||||||
@import "./structures/_HomePage.scss";
|
@import "./structures/_HomePage.scss";
|
||||||
@import "./structures/_LeftPanel2.scss";
|
@import "./structures/_LeftPanel.scss";
|
||||||
@import "./structures/_MainSplit.scss";
|
@import "./structures/_MainSplit.scss";
|
||||||
@import "./structures/_MatrixChat.scss";
|
@import "./structures/_MatrixChat.scss";
|
||||||
@import "./structures/_MyGroups.scss";
|
@import "./structures/_MyGroups.scss";
|
||||||
|
|
|
@ -14,11 +14,9 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14367
|
|
||||||
|
|
||||||
$tagPanelWidth: 56px; // only applies in this file, used for calculations
|
$tagPanelWidth: 56px; // only applies in this file, used for calculations
|
||||||
|
|
||||||
.mx_LeftPanel2 {
|
.mx_LeftPanel {
|
||||||
background-color: $roomlist2-bg-color;
|
background-color: $roomlist2-bg-color;
|
||||||
min-width: 260px;
|
min-width: 260px;
|
||||||
max-width: 50%;
|
max-width: 50%;
|
||||||
|
@ -26,7 +24,7 @@ $tagPanelWidth: 56px; // only applies in this file, used for calculations
|
||||||
// Create a row-based flexbox for the TagPanel and the room list
|
// Create a row-based flexbox for the TagPanel and the room list
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
.mx_LeftPanel2_tagPanelContainer {
|
.mx_LeftPanel_tagPanelContainer {
|
||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
flex-basis: $tagPanelWidth;
|
flex-basis: $tagPanelWidth;
|
||||||
|
@ -38,15 +36,15 @@ $tagPanelWidth: 56px; // only applies in this file, used for calculations
|
||||||
// TagPanel handles its own CSS
|
// TagPanel handles its own CSS
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not(.mx_LeftPanel2_hasTagPanel) {
|
&:not(.mx_LeftPanel_hasTagPanel) {
|
||||||
.mx_LeftPanel2_roomListContainer {
|
.mx_LeftPanel_roomListContainer {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: The 'room list' in this context is actually everything that isn't the tag
|
// Note: The 'room list' in this context is actually everything that isn't the tag
|
||||||
// panel, such as the menu options, breadcrumbs, filtering, etc
|
// panel, such as the menu options, breadcrumbs, filtering, etc
|
||||||
.mx_LeftPanel2_roomListContainer {
|
.mx_LeftPanel_roomListContainer {
|
||||||
width: calc(100% - $tagPanelWidth);
|
width: calc(100% - $tagPanelWidth);
|
||||||
background-color: $roomlist2-bg-color;
|
background-color: $roomlist2-bg-color;
|
||||||
|
|
||||||
|
@ -54,7 +52,7 @@ $tagPanelWidth: 56px; // only applies in this file, used for calculations
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
.mx_LeftPanel2_userHeader {
|
.mx_LeftPanel_userHeader {
|
||||||
/* 12px top, 12px sides, 20px bottom (using 13px bottom to account
|
/* 12px top, 12px sides, 20px bottom (using 13px bottom to account
|
||||||
* for internal whitespace in the breadcrumbs)
|
* for internal whitespace in the breadcrumbs)
|
||||||
*/
|
*/
|
||||||
|
@ -66,7 +64,7 @@ $tagPanelWidth: 56px; // only applies in this file, used for calculations
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_LeftPanel2_breadcrumbsContainer {
|
.mx_LeftPanel_breadcrumbsContainer {
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
overflow-x: scroll;
|
overflow-x: scroll;
|
||||||
margin: 12px 12px 0 12px;
|
margin: 12px 12px 0 12px;
|
||||||
|
@ -89,7 +87,7 @@ $tagPanelWidth: 56px; // only applies in this file, used for calculations
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_LeftPanel2_filterContainer {
|
.mx_LeftPanel_filterContainer {
|
||||||
margin-left: 12px;
|
margin-left: 12px;
|
||||||
margin-right: 12px;
|
margin-right: 12px;
|
||||||
|
|
||||||
|
@ -99,7 +97,7 @@ $tagPanelWidth: 56px; // only applies in this file, used for calculations
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
.mx_RoomSearch_expanded + .mx_LeftPanel2_exploreButton {
|
.mx_RoomSearch_expanded + .mx_LeftPanel_exploreButton {
|
||||||
// Cheaty way to return the occupied space to the filter input
|
// Cheaty way to return the occupied space to the filter input
|
||||||
flex-basis: 0;
|
flex-basis: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -112,7 +110,7 @@ $tagPanelWidth: 56px; // only applies in this file, used for calculations
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_LeftPanel2_exploreButton {
|
.mx_LeftPanel_exploreButton {
|
||||||
width: 28px;
|
width: 28px;
|
||||||
height: 28px;
|
height: 28px;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
|
@ -136,7 +134,7 @@ $tagPanelWidth: 56px; // only applies in this file, used for calculations
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_LeftPanel2_roomListWrapper {
|
.mx_LeftPanel_roomListWrapper {
|
||||||
// Create a flexbox to ensure the containing items cause appropriate overflow.
|
// Create a flexbox to ensure the containing items cause appropriate overflow.
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
|
@ -145,16 +143,16 @@ $tagPanelWidth: 56px; // only applies in this file, used for calculations
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
margin-top: 10px; // so we're not up against the search/filter
|
margin-top: 10px; // so we're not up against the search/filter
|
||||||
|
|
||||||
&.mx_LeftPanel2_roomListWrapper_stickyBottom {
|
&.mx_LeftPanel_roomListWrapper_stickyBottom {
|
||||||
padding-bottom: 32px;
|
padding-bottom: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.mx_LeftPanel2_roomListWrapper_stickyTop {
|
&.mx_LeftPanel_roomListWrapper_stickyTop {
|
||||||
padding-top: 32px;
|
padding-top: 32px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_LeftPanel2_actualRoomListContainer {
|
.mx_LeftPanel_actualRoomListContainer {
|
||||||
flex-grow: 1; // fill the available space
|
flex-grow: 1; // fill the available space
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -167,26 +165,26 @@ $tagPanelWidth: 56px; // only applies in this file, used for calculations
|
||||||
}
|
}
|
||||||
|
|
||||||
// These styles override the defaults for the minimized (66px) layout
|
// These styles override the defaults for the minimized (66px) layout
|
||||||
&.mx_LeftPanel2_minimized {
|
&.mx_LeftPanel_minimized {
|
||||||
min-width: unset;
|
min-width: unset;
|
||||||
|
|
||||||
// We have to forcefully set the width to override the resizer's style attribute.
|
// We have to forcefully set the width to override the resizer's style attribute.
|
||||||
&.mx_LeftPanel2_hasTagPanel {
|
&.mx_LeftPanel_hasTagPanel {
|
||||||
width: calc(68px + $tagPanelWidth) !important;
|
width: calc(68px + $tagPanelWidth) !important;
|
||||||
}
|
}
|
||||||
&:not(.mx_LeftPanel2_hasTagPanel) {
|
&:not(.mx_LeftPanel_hasTagPanel) {
|
||||||
width: 68px !important;
|
width: 68px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_LeftPanel2_roomListContainer {
|
.mx_LeftPanel_roomListContainer {
|
||||||
width: 68px;
|
width: 68px;
|
||||||
|
|
||||||
.mx_LeftPanel2_filterContainer {
|
.mx_LeftPanel_filterContainer {
|
||||||
// Organize the flexbox into a centered column layout
|
// Organize the flexbox into a centered column layout
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
.mx_LeftPanel2_exploreButton {
|
.mx_LeftPanel_exploreButton {
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
|
@ -66,7 +66,7 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
|
|
||||||
/* not the left panel, and not the resize handle, so the roomview/groupview/... */
|
/* not the left panel, and not the resize handle, so the roomview/groupview/... */
|
||||||
.mx_MatrixChat > :not(.mx_LeftPanel_container):not(.mx_LeftPanel2):not(.mx_ResizeHandle) {
|
.mx_MatrixChat > :not(.mx_LeftPanel):not(.mx_ResizeHandle) {
|
||||||
background-color: $primary-bg-color;
|
background-color: $primary-bg-color;
|
||||||
|
|
||||||
flex: 1 1 0;
|
flex: 1 1 0;
|
||||||
|
|
|
@ -43,7 +43,7 @@ limitations under the License.
|
||||||
// all works by ensuring the header text has a fixed height when sticky so the
|
// all works by ensuring the header text has a fixed height when sticky so the
|
||||||
// fixed height of the container can maintain the scroll position.
|
// fixed height of the container can maintain the scroll position.
|
||||||
|
|
||||||
// The combined height must be set in the LeftPanel2 component for sticky headers
|
// The combined height must be set in the LeftPanel component for sticky headers
|
||||||
// to work correctly.
|
// to work correctly.
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
// it can be blurred by the tag panel and room list
|
// it can be blurred by the tag panel and room list
|
||||||
|
|
||||||
@supports (backdrop-filter: none) {
|
@supports (backdrop-filter: none) {
|
||||||
.mx_LeftPanel2 {
|
.mx_LeftPanel {
|
||||||
background-image: var(--avatar-url);
|
background-image: var(--avatar-url);
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
backdrop-filter: blur($tagpanel-background-blur-amount);
|
backdrop-filter: blur($tagpanel-background-blur-amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_LeftPanel2 .mx_LeftPanel2_roomListContainer {
|
.mx_LeftPanel .mx_LeftPanel_roomListContainer {
|
||||||
backdrop-filter: blur($roomlist-background-blur-amount);
|
backdrop-filter: blur($roomlist-background-blur-amount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,8 +36,6 @@ import {Key} from "../../Keyboard";
|
||||||
import IndicatorScrollbar from "../structures/IndicatorScrollbar";
|
import IndicatorScrollbar from "../structures/IndicatorScrollbar";
|
||||||
import AccessibleTooltipButton from "../views/elements/AccessibleTooltipButton";
|
import AccessibleTooltipButton from "../views/elements/AccessibleTooltipButton";
|
||||||
|
|
||||||
// TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14367
|
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
isMinimized: boolean;
|
isMinimized: boolean;
|
||||||
resizeNotifier: ResizeNotifier;
|
resizeNotifier: ResizeNotifier;
|
||||||
|
@ -58,7 +56,7 @@ const cssClasses = [
|
||||||
"mx_RoomSublist2_showNButton",
|
"mx_RoomSublist2_showNButton",
|
||||||
];
|
];
|
||||||
|
|
||||||
export default class LeftPanel2 extends React.Component<IProps, IState> {
|
export default class LeftPanel extends React.Component<IProps, IState> {
|
||||||
private listContainerRef: React.RefObject<HTMLDivElement> = createRef();
|
private listContainerRef: React.RefObject<HTMLDivElement> = createRef();
|
||||||
private tagPanelWatcherRef: string;
|
private tagPanelWatcherRef: string;
|
||||||
private focusedElement = null;
|
private focusedElement = null;
|
||||||
|
@ -222,16 +220,16 @@ export default class LeftPanel2 extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
// add appropriate sticky classes to wrapper so it has
|
// add appropriate sticky classes to wrapper so it has
|
||||||
// the necessary top/bottom padding to put the sticky header in
|
// the necessary top/bottom padding to put the sticky header in
|
||||||
const listWrapper = list.parentElement; // .mx_LeftPanel2_roomListWrapper
|
const listWrapper = list.parentElement; // .mx_LeftPanel_roomListWrapper
|
||||||
if (lastTopHeader) {
|
if (lastTopHeader) {
|
||||||
listWrapper.classList.add("mx_LeftPanel2_roomListWrapper_stickyTop");
|
listWrapper.classList.add("mx_LeftPanel_roomListWrapper_stickyTop");
|
||||||
} else {
|
} else {
|
||||||
listWrapper.classList.remove("mx_LeftPanel2_roomListWrapper_stickyTop");
|
listWrapper.classList.remove("mx_LeftPanel_roomListWrapper_stickyTop");
|
||||||
}
|
}
|
||||||
if (firstBottomHeader) {
|
if (firstBottomHeader) {
|
||||||
listWrapper.classList.add("mx_LeftPanel2_roomListWrapper_stickyBottom");
|
listWrapper.classList.add("mx_LeftPanel_roomListWrapper_stickyBottom");
|
||||||
} else {
|
} else {
|
||||||
listWrapper.classList.remove("mx_LeftPanel2_roomListWrapper_stickyBottom");
|
listWrapper.classList.remove("mx_LeftPanel_roomListWrapper_stickyBottom");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,7 +313,7 @@ export default class LeftPanel2 extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
private renderHeader(): React.ReactNode {
|
private renderHeader(): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<div className="mx_LeftPanel2_userHeader">
|
<div className="mx_LeftPanel_userHeader">
|
||||||
<UserMenu isMinimized={this.props.isMinimized} />
|
<UserMenu isMinimized={this.props.isMinimized} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -325,7 +323,7 @@ export default class LeftPanel2 extends React.Component<IProps, IState> {
|
||||||
if (this.state.showBreadcrumbs && !this.props.isMinimized) {
|
if (this.state.showBreadcrumbs && !this.props.isMinimized) {
|
||||||
return (
|
return (
|
||||||
<IndicatorScrollbar
|
<IndicatorScrollbar
|
||||||
className="mx_LeftPanel2_breadcrumbsContainer mx_AutoHideScrollbar"
|
className="mx_LeftPanel_breadcrumbsContainer mx_AutoHideScrollbar"
|
||||||
verticalScrollsHorizontally={true}
|
verticalScrollsHorizontally={true}
|
||||||
>
|
>
|
||||||
<RoomBreadcrumbs2 />
|
<RoomBreadcrumbs2 />
|
||||||
|
@ -337,7 +335,7 @@ export default class LeftPanel2 extends React.Component<IProps, IState> {
|
||||||
private renderSearchExplore(): React.ReactNode {
|
private renderSearchExplore(): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="mx_LeftPanel2_filterContainer"
|
className="mx_LeftPanel_filterContainer"
|
||||||
onFocus={this.onFocus}
|
onFocus={this.onFocus}
|
||||||
onBlur={this.onBlur}
|
onBlur={this.onBlur}
|
||||||
onKeyDown={this.onKeyDown}
|
onKeyDown={this.onKeyDown}
|
||||||
|
@ -349,7 +347,7 @@ export default class LeftPanel2 extends React.Component<IProps, IState> {
|
||||||
onEnter={this.onEnter}
|
onEnter={this.onEnter}
|
||||||
/>
|
/>
|
||||||
<AccessibleTooltipButton
|
<AccessibleTooltipButton
|
||||||
className="mx_LeftPanel2_exploreButton"
|
className="mx_LeftPanel_exploreButton"
|
||||||
onClick={this.onExplore}
|
onClick={this.onExplore}
|
||||||
title={_t("Explore rooms")}
|
title={_t("Explore rooms")}
|
||||||
/>
|
/>
|
||||||
|
@ -359,7 +357,7 @@ export default class LeftPanel2 extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
public render(): React.ReactNode {
|
public render(): React.ReactNode {
|
||||||
const tagPanel = !this.state.showTagPanel ? null : (
|
const tagPanel = !this.state.showTagPanel ? null : (
|
||||||
<div className="mx_LeftPanel2_tagPanelContainer">
|
<div className="mx_LeftPanel_tagPanelContainer">
|
||||||
<TagPanel/>
|
<TagPanel/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -376,24 +374,24 @@ export default class LeftPanel2 extends React.Component<IProps, IState> {
|
||||||
/>;
|
/>;
|
||||||
|
|
||||||
const containerClasses = classNames({
|
const containerClasses = classNames({
|
||||||
"mx_LeftPanel2": true,
|
"mx_LeftPanel": true,
|
||||||
"mx_LeftPanel2_hasTagPanel": !!tagPanel,
|
"mx_LeftPanel_hasTagPanel": !!tagPanel,
|
||||||
"mx_LeftPanel2_minimized": this.props.isMinimized,
|
"mx_LeftPanel_minimized": this.props.isMinimized,
|
||||||
});
|
});
|
||||||
|
|
||||||
const roomListClasses = classNames(
|
const roomListClasses = classNames(
|
||||||
"mx_LeftPanel2_actualRoomListContainer",
|
"mx_LeftPanel_actualRoomListContainer",
|
||||||
"mx_AutoHideScrollbar",
|
"mx_AutoHideScrollbar",
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={containerClasses}>
|
<div className={containerClasses}>
|
||||||
{tagPanel}
|
{tagPanel}
|
||||||
<aside className="mx_LeftPanel2_roomListContainer">
|
<aside className="mx_LeftPanel_roomListContainer">
|
||||||
{this.renderHeader()}
|
{this.renderHeader()}
|
||||||
{this.renderSearchExplore()}
|
{this.renderSearchExplore()}
|
||||||
{this.renderBreadcrumbs()}
|
{this.renderBreadcrumbs()}
|
||||||
<div className="mx_LeftPanel2_roomListWrapper">
|
<div className="mx_LeftPanel_roomListWrapper">
|
||||||
<div
|
<div
|
||||||
className={roomListClasses}
|
className={roomListClasses}
|
||||||
onScroll={this.onScroll}
|
onScroll={this.onScroll}
|
|
@ -50,7 +50,7 @@ import {
|
||||||
hideToast as hideServerLimitToast
|
hideToast as hideServerLimitToast
|
||||||
} from "../../toasts/ServerLimitToast";
|
} from "../../toasts/ServerLimitToast";
|
||||||
import { Action } from "../../dispatcher/actions";
|
import { Action } from "../../dispatcher/actions";
|
||||||
import LeftPanel2 from "./LeftPanel2";
|
import LeftPanel from "./LeftPanel";
|
||||||
import CallContainer from '../views/voip/CallContainer';
|
import CallContainer from '../views/voip/CallContainer';
|
||||||
import { ViewRoomDeltaPayload } from "../../dispatcher/payloads/ViewRoomDeltaPayload";
|
import { ViewRoomDeltaPayload } from "../../dispatcher/payloads/ViewRoomDeltaPayload";
|
||||||
import RoomListStore from "../../stores/room-list/RoomListStore";
|
import RoomListStore from "../../stores/room-list/RoomListStore";
|
||||||
|
@ -661,7 +661,7 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
const leftPanel = (
|
const leftPanel = (
|
||||||
<LeftPanel2
|
<LeftPanel
|
||||||
isMinimized={this.props.collapseLhs || false}
|
isMinimized={this.props.collapseLhs || false}
|
||||||
resizeNotifier={this.props.resizeNotifier}
|
resizeNotifier={this.props.resizeNotifier}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -326,7 +326,7 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
|
||||||
const possibleSticky = this.headerButton.current.parentElement;
|
const possibleSticky = this.headerButton.current.parentElement;
|
||||||
const sublist = possibleSticky.parentElement.parentElement;
|
const sublist = possibleSticky.parentElement.parentElement;
|
||||||
const list = sublist.parentElement.parentElement;
|
const list = sublist.parentElement.parentElement;
|
||||||
// the scrollTop is capped at the height of the header in LeftPanel2, the top header is always sticky
|
// the scrollTop is capped at the height of the header in LeftPanel, the top header is always sticky
|
||||||
const isAtTop = list.scrollTop <= HEADER_HEIGHT;
|
const isAtTop = list.scrollTop <= HEADER_HEIGHT;
|
||||||
const isAtBottom = list.scrollTop >= list.scrollHeight - list.offsetHeight;
|
const isAtBottom = list.scrollTop >= list.scrollHeight - list.offsetHeight;
|
||||||
const isStickyTop = possibleSticky.classList.contains('mx_RoomSublist2_headerContainer_stickyTop');
|
const isStickyTop = possibleSticky.classList.contains('mx_RoomSublist2_headerContainer_stickyTop');
|
||||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
async function openRoomDirectory(session) {
|
async function openRoomDirectory(session) {
|
||||||
const roomDirectoryButton = await session.query('.mx_LeftPanel2_exploreButton');
|
const roomDirectoryButton = await session.query('.mx_LeftPanel_exploreButton');
|
||||||
await roomDirectoryButton.click();
|
await roomDirectoryButton.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue