mirror of https://github.com/vector-im/riot-web
				
				
				
			Merge pull request #6659 from matrix-org/palid/fix/backdrop-blur
Optimize background image from avatar on left panelpull/21833/head
						commit
						6205cbbdec
					
				|  | @ -64,7 +64,6 @@ | |||
|     "cheerio": "^1.0.0-rc.9", | ||||
|     "classnames": "^2.2.6", | ||||
|     "commonmark": "^0.29.3", | ||||
|     "context-filter-polyfill": "^0.2.4", | ||||
|     "counterpart": "^0.18.6", | ||||
|     "diff-dom": "^4.2.2", | ||||
|     "diff-match-patch": "^1.0.5", | ||||
|  | @ -196,7 +195,6 @@ | |||
|       "decoderWorker\\.min\\.js": "<rootDir>/__mocks__/empty.js", | ||||
|       "decoderWorker\\.min\\.wasm": "<rootDir>/__mocks__/empty.js", | ||||
|       "waveWorker\\.min\\.js": "<rootDir>/__mocks__/empty.js", | ||||
|       "context-filter-polyfill": "<rootDir>/__mocks__/empty.js", | ||||
|       "workers/(.+)\\.worker\\.ts": "<rootDir>/__mocks__/workerMock.js", | ||||
|       "RecorderWorklet": "<rootDir>/__mocks__/empty.js" | ||||
|     }, | ||||
|  |  | |||
|  | @ -21,19 +21,10 @@ limitations under the License. | |||
|     height: 100vh; | ||||
|     width: 100%; | ||||
|     overflow: hidden; | ||||
| 
 | ||||
|     &::before { | ||||
|         content: " "; | ||||
|         position: absolute; | ||||
|         left: 0; | ||||
|         top: 0; | ||||
|         height: 100vh; | ||||
|         width: 100%; | ||||
|         background-color: var(--lp-background-overlay); | ||||
|     } | ||||
|     filter: blur(var(--lp-background-blur)); | ||||
| } | ||||
| 
 | ||||
| .mx_BackdropPanel--canvas { | ||||
| .mx_BackdropPanel--image { | ||||
|     position: absolute; | ||||
|     top: 0; | ||||
|     left: 0; | ||||
|  | @ -41,11 +32,4 @@ limitations under the License. | |||
|     z-index: 0; | ||||
|     pointer-events: none; | ||||
|     overflow: hidden; | ||||
| 
 | ||||
|     &:nth-of-type(2n-1) { | ||||
|         opacity: 0.2; | ||||
|     } | ||||
|     &:nth-of-type(2n) { | ||||
|         opacity: 0.1; | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -14,13 +14,23 @@ See the License for the specific language governing permissions and | |||
| limitations under the License. | ||||
| */ | ||||
| 
 | ||||
| .mx_MatrixChat--with-avatar { | ||||
|     .mx_GroupFilterPanel { | ||||
|         background-color: transparent; | ||||
|     } | ||||
| $groupFilterPanelWidth: 56px; // only applies in this file, used for calculations | ||||
| 
 | ||||
| .mx_GroupFilterPanelContainer { | ||||
|     flex-grow: 0; | ||||
|     flex-shrink: 0; | ||||
|     width: $groupFilterPanelWidth; | ||||
|     height: 100%; | ||||
| 
 | ||||
|     // Create another flexbox so the GroupFilterPanel fills the container | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
| 
 | ||||
|     // GroupFilterPanel handles its own CSS | ||||
| } | ||||
| 
 | ||||
| .mx_GroupFilterPanel { | ||||
|     z-index: 1; | ||||
|     background-color: $groupFilterPanel-bg-color; | ||||
|     flex: 1; | ||||
|     cursor: pointer; | ||||
|  |  | |||
|  | @ -14,7 +14,6 @@ See the License for the specific language governing permissions and | |||
| limitations under the License. | ||||
| */ | ||||
| 
 | ||||
| $groupFilterPanelWidth: 56px; // only applies in this file, used for calculations | ||||
| $roomListCollapsedWidth: 68px; | ||||
| 
 | ||||
| .mx_MatrixChat--with-avatar { | ||||
|  | @ -27,8 +26,17 @@ $roomListCollapsedWidth: 68px; | |||
| .mx_LeftPanel_wrapper { | ||||
|     display: flex; | ||||
|     max-width: 50%; | ||||
| 
 | ||||
|     .mx_LeftPanel_wrapper--user { | ||||
|         background-color: $roomlist-bg-color; | ||||
|         display: flex; | ||||
|         overflow: hidden; | ||||
|         position: relative; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| .mx_LeftPanel { | ||||
|     background-color: $roomlist-bg-color; | ||||
|     // TODO decrease this once Spaces launches as it'll no longer need to include the 56px Community Panel | ||||
|  | @ -39,19 +47,6 @@ $roomListCollapsedWidth: 68px; | |||
|     contain: content; | ||||
|     position: relative; | ||||
| 
 | ||||
|     .mx_LeftPanel_GroupFilterPanelContainer { | ||||
|         flex-grow: 0; | ||||
|         flex-shrink: 0; | ||||
|         flex-basis: $groupFilterPanelWidth; | ||||
|         height: 100%; | ||||
| 
 | ||||
|         // Create another flexbox so the GroupFilterPanel fills the container | ||||
|         display: flex; | ||||
|         flex-direction: column; | ||||
| 
 | ||||
|         // GroupFilterPanel handles its own CSS | ||||
|     } | ||||
| 
 | ||||
|     // Note: The 'room list' in this context is actually everything that isn't the tag | ||||
|     // panel, such as the menu options, breadcrumbs, filtering, etc | ||||
|     .mx_LeftPanel_roomListContainer { | ||||
|  |  | |||
|  | @ -22,18 +22,14 @@ $activeBorderTransparentGap: 1px; | |||
| $activeBackgroundColor: $roomtile-selected-bg-color; | ||||
| $activeBorderColor: $secondary-fg-color; | ||||
| 
 | ||||
| .mx_MatrixChat--with-avatar { | ||||
|     .mx_SpacePanel { | ||||
|         background-color: transparent; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| .mx_SpacePanel { | ||||
|     background-color: $groupFilterPanel-bg-color; | ||||
|     flex: 0 0 auto; | ||||
|     padding: 0; | ||||
|     margin: 0; | ||||
|     position: relative; | ||||
|     // Fix for the blurred avatar-background | ||||
|     z-index: 1; | ||||
| 
 | ||||
|     // Create another flexbox so the Panel fills the container | ||||
|     display: flex; | ||||
|  |  | |||
|  | @ -240,9 +240,7 @@ $appearance-tab-border-color: $room-highlight-color; | |||
| 
 | ||||
| // blur amounts for left left panel (only for element theme) | ||||
| :root { | ||||
|     --llp-background-blur: 160px; | ||||
|     --lp-background-blur: 90px; | ||||
|     --lp-background-overlay: rgba(255, 255, 255, 0.055); | ||||
|     --lp-background-blur: 45px; | ||||
| } | ||||
| 
 | ||||
| $composer-shadow-color: rgba(0, 0, 0, 0.28); | ||||
|  |  | |||
|  | @ -363,9 +363,7 @@ $appearance-tab-border-color: $input-darker-bg-color; | |||
| 
 | ||||
| // blur amounts for left left panel (only for element theme) | ||||
| :root { | ||||
|     --llp-background-blur: 120px; | ||||
|     --lp-background-blur: 60px; | ||||
|     --lp-background-overlay: rgba(0, 0, 0, 0.055); | ||||
|     --lp-background-blur: 30px; | ||||
| } | ||||
| $composer-shadow-color: rgba(0, 0, 0, 0.04); | ||||
| 
 | ||||
|  |  | |||
|  | @ -14,153 +14,31 @@ See the License for the specific language governing permissions and | |||
| limitations under the License. | ||||
| */ | ||||
| 
 | ||||
| import React, { createRef } from "react"; | ||||
| import "context-filter-polyfill"; | ||||
| 
 | ||||
| import UIStore from "../../stores/UIStore"; | ||||
| import React, { CSSProperties } from "react"; | ||||
| 
 | ||||
| interface IProps { | ||||
|     backgroundImage?: CanvasImageSource; | ||||
|     backgroundImage?: string; | ||||
|     blurMultiplier?: number; | ||||
| } | ||||
| 
 | ||||
| interface IState { | ||||
|     // Left Panel image
 | ||||
|     lpImage?: string; | ||||
|     // Left-left panel image
 | ||||
|     llpImage?: string; | ||||
| } | ||||
| export const BackdropPanel: React.FC<IProps> = ({ backgroundImage, blurMultiplier }) => { | ||||
|     if (!backgroundImage) return null; | ||||
| 
 | ||||
| export default class BackdropPanel extends React.PureComponent<IProps, IState> { | ||||
|     private leftLeftPanelRef = createRef<HTMLCanvasElement>(); | ||||
|     private leftPanelRef = createRef<HTMLCanvasElement>(); | ||||
| 
 | ||||
|     private sizes = { | ||||
|         leftLeftPanelWidth: 0, | ||||
|         leftPanelWidth: 0, | ||||
|         height: 0, | ||||
|     }; | ||||
|     private style = getComputedStyle(document.documentElement); | ||||
| 
 | ||||
|     public state: IState = {}; | ||||
| 
 | ||||
|     public componentDidMount() { | ||||
|         UIStore.instance.on("SpacePanel", this.onResize); | ||||
|         UIStore.instance.on("GroupFilterPanelContainer", this.onResize); | ||||
|         this.onResize(); | ||||
|     } | ||||
| 
 | ||||
|     public componentWillUnmount() { | ||||
|         UIStore.instance.off("SpacePanel", this.onResize); | ||||
|         UIStore.instance.on("GroupFilterPanelContainer", this.onResize); | ||||
|     } | ||||
| 
 | ||||
|     public componentDidUpdate(prevProps: IProps) { | ||||
|         if (prevProps.backgroundImage !== this.props.backgroundImage) { | ||||
|             this.setState({}); | ||||
|             this.onResize(); | ||||
|     const styles: CSSProperties = {}; | ||||
|     if (blurMultiplier) { | ||||
|         const rootStyle = getComputedStyle(document.documentElement); | ||||
|         const blurValue = rootStyle.getPropertyValue('--lp-background-blur'); | ||||
|         const pixelsValue = blurValue.replace('px', ''); | ||||
|         const parsed = parseInt(pixelsValue, 10); | ||||
|         if (!isNaN(parsed)) { | ||||
|             styles.filter = `blur(${parsed * blurMultiplier}px)`; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private onResize = () => { | ||||
|         if (this.props.backgroundImage) { | ||||
|             const groupFilterPanelDimensions = UIStore.instance.getElementDimensions("GroupFilterPanelContainer"); | ||||
|             const spacePanelDimensions = UIStore.instance.getElementDimensions("SpacePanel"); | ||||
|             const roomListDimensions = UIStore.instance.getElementDimensions("LeftPanel"); | ||||
|             this.sizes = { | ||||
|                 leftLeftPanelWidth: spacePanelDimensions?.width ?? groupFilterPanelDimensions?.width ?? 0, | ||||
|                 leftPanelWidth: roomListDimensions?.width ?? 0, | ||||
|                 height: UIStore.instance.windowHeight, | ||||
|             }; | ||||
|             this.refreshBackdropImage(); | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     private refreshBackdropImage = (): void => { | ||||
|         const leftLeftPanelContext = this.leftLeftPanelRef.current.getContext("2d"); | ||||
|         const leftPanelContext = this.leftPanelRef.current.getContext("2d"); | ||||
|         const { leftLeftPanelWidth, leftPanelWidth, height } = this.sizes; | ||||
|         const width = leftLeftPanelWidth + leftPanelWidth; | ||||
|         const { backgroundImage } = this.props; | ||||
| 
 | ||||
|         const imageWidth = (backgroundImage as ImageBitmap).width; | ||||
|         const imageHeight = (backgroundImage as ImageBitmap).height; | ||||
| 
 | ||||
|         const contentRatio = imageWidth / imageHeight; | ||||
|         const containerRatio = width / height; | ||||
|         let resultHeight; | ||||
|         let resultWidth; | ||||
|         if (contentRatio > containerRatio) { | ||||
|             resultHeight = height; | ||||
|             resultWidth = height * contentRatio; | ||||
|         } else { | ||||
|             resultWidth = width; | ||||
|             resultHeight = width / contentRatio; | ||||
|         } | ||||
| 
 | ||||
|         // This value has been chosen to be as close with rendering as the css-only
 | ||||
|         // backdrop-filter: blur effect was, mostly takes effect for vertical pictures.
 | ||||
|         const x = width * 0.1; | ||||
|         const y = (height - resultHeight) / 2; | ||||
| 
 | ||||
|         this.leftLeftPanelRef.current.width = leftLeftPanelWidth; | ||||
|         this.leftLeftPanelRef.current.height = height; | ||||
|         this.leftPanelRef.current.width = (window.screen.width * 0.5); | ||||
|         this.leftPanelRef.current.height = height; | ||||
| 
 | ||||
|         const spacesBlur = this.style.getPropertyValue('--llp-background-blur'); | ||||
|         const roomListBlur = this.style.getPropertyValue('--lp-background-blur'); | ||||
| 
 | ||||
|         leftLeftPanelContext.filter = `blur(${spacesBlur})`; | ||||
|         leftPanelContext.filter = `blur(${roomListBlur})`; | ||||
|         leftLeftPanelContext.drawImage( | ||||
|             backgroundImage, | ||||
|             0, 0, | ||||
|             imageWidth, imageHeight, | ||||
|             x, | ||||
|             y, | ||||
|             resultWidth, | ||||
|             resultHeight, | ||||
|         ); | ||||
|         leftPanelContext.drawImage( | ||||
|             backgroundImage, | ||||
|             0, 0, | ||||
|             imageWidth, imageHeight, | ||||
|             x - leftLeftPanelWidth, | ||||
|             y, | ||||
|             resultWidth, | ||||
|             resultHeight, | ||||
|         ); | ||||
|         this.setState({ | ||||
|             lpImage: this.leftPanelRef.current.toDataURL('image/jpeg', 1), | ||||
|             llpImage: this.leftLeftPanelRef.current.toDataURL('image/jpeg', 1), | ||||
| 
 | ||||
|         }); | ||||
|     }; | ||||
| 
 | ||||
|     public render() { | ||||
|         if (!this.props.backgroundImage) return null; | ||||
|         return <div className="mx_BackdropPanel"> | ||||
|             { this.state?.llpImage !== 'data:,' && <img | ||||
|                 className="mx_BackdropPanel--canvas" | ||||
|                 src={this.state.llpImage} /> } | ||||
| 
 | ||||
|             { this.state?.lpImage !== 'data:,' && <img | ||||
|                 className="mx_BackdropPanel--canvas" | ||||
|                 src={this.state.lpImage} /> } | ||||
|             <canvas | ||||
|                 ref={this.leftLeftPanelRef} | ||||
|                 className="mx_BackdropPanel--canvas" | ||||
|                 style={{ | ||||
|                     display: this.state.lpImage ? 'none' : 'block', | ||||
|                 }} | ||||
|             /> | ||||
|             <canvas | ||||
|                 style={{ | ||||
|                     display: this.state.lpImage ? 'none' : 'block', | ||||
|                 }} | ||||
|                 ref={this.leftPanelRef} | ||||
|                 className="mx_BackdropPanel--canvas" | ||||
|             /> | ||||
|         </div>; | ||||
|     } | ||||
| } | ||||
|     return <div className="mx_BackdropPanel"> | ||||
|         <img | ||||
|             style={styles} | ||||
|             className="mx_BackdropPanel--image" | ||||
|             src={backgroundImage} /> | ||||
|     </div>; | ||||
| }; | ||||
| export default BackdropPanel; | ||||
|  |  | |||
|  | @ -19,8 +19,6 @@ import { createRef } from "react"; | |||
| import classNames from "classnames"; | ||||
| import { Room } from "matrix-js-sdk/src/models/room"; | ||||
| 
 | ||||
| import GroupFilterPanel from "./GroupFilterPanel"; | ||||
| import CustomRoomTagPanel from "./CustomRoomTagPanel"; | ||||
| import dis from "../../dispatcher/dispatcher"; | ||||
| import { _t } from "../../languageHandler"; | ||||
| import RoomList from "../views/rooms/RoomList"; | ||||
|  | @ -33,7 +31,6 @@ import RoomBreadcrumbs from "../views/rooms/RoomBreadcrumbs"; | |||
| import { BreadcrumbsStore } from "../../stores/BreadcrumbsStore"; | ||||
| import { UPDATE_EVENT } from "../../stores/AsyncStore"; | ||||
| import ResizeNotifier from "../../utils/ResizeNotifier"; | ||||
| import SettingsStore from "../../settings/SettingsStore"; | ||||
| import RoomListStore, { LISTS_UPDATE_EVENT } from "../../stores/room-list/RoomListStore"; | ||||
| import IndicatorScrollbar from "../structures/IndicatorScrollbar"; | ||||
| import AccessibleTooltipButton from "../views/elements/AccessibleTooltipButton"; | ||||
|  | @ -51,7 +48,6 @@ interface IProps { | |||
| 
 | ||||
| interface IState { | ||||
|     showBreadcrumbs: boolean; | ||||
|     showGroupFilterPanel: boolean; | ||||
|     activeSpace?: Room; | ||||
| } | ||||
| 
 | ||||
|  | @ -68,9 +64,6 @@ const cssClasses = [ | |||
| export default class LeftPanel extends React.Component<IProps, IState> { | ||||
|     private ref: React.RefObject<HTMLDivElement> = createRef(); | ||||
|     private listContainerRef: React.RefObject<HTMLDivElement> = createRef(); | ||||
|     private groupFilterPanelWatcherRef: string; | ||||
|     private groupFilterPanelContainer = createRef<HTMLDivElement>(); | ||||
|     private bgImageWatcherRef: string; | ||||
|     private focusedElement = null; | ||||
|     private isDoingStickyHeaders = false; | ||||
| 
 | ||||
|  | @ -79,25 +72,17 @@ export default class LeftPanel extends React.Component<IProps, IState> { | |||
| 
 | ||||
|         this.state = { | ||||
|             showBreadcrumbs: BreadcrumbsStore.instance.visible, | ||||
|             showGroupFilterPanel: SettingsStore.getValue('TagPanel.enableTagPanel'), | ||||
|             activeSpace: SpaceStore.instance.activeSpace, | ||||
|         }; | ||||
| 
 | ||||
|         BreadcrumbsStore.instance.on(UPDATE_EVENT, this.onBreadcrumbsUpdate); | ||||
|         RoomListStore.instance.on(LISTS_UPDATE_EVENT, this.onBreadcrumbsUpdate); | ||||
|         SpaceStore.instance.on(UPDATE_SELECTED_SPACE, this.updateActiveSpace); | ||||
|         this.groupFilterPanelWatcherRef = SettingsStore.watchSetting("TagPanel.enableTagPanel", null, () => { | ||||
|             this.setState({ showGroupFilterPanel: SettingsStore.getValue("TagPanel.enableTagPanel") }); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     public componentDidMount() { | ||||
|         UIStore.instance.trackElementDimensions("LeftPanel", this.ref.current); | ||||
|         UIStore.instance.trackElementDimensions("ListContainer", this.listContainerRef.current); | ||||
|         if (this.groupFilterPanelContainer.current) { | ||||
|             const componentName = "GroupFilterPanelContainer"; | ||||
|             UIStore.instance.trackElementDimensions(componentName, this.groupFilterPanelContainer.current); | ||||
|         } | ||||
|         UIStore.instance.on("ListContainer", this.refreshStickyHeaders); | ||||
|         // Using the passive option to not block the main thread
 | ||||
|         // https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#improving_scrolling_performance_with_passive_listeners
 | ||||
|  | @ -105,7 +90,6 @@ export default class LeftPanel extends React.Component<IProps, IState> { | |||
|     } | ||||
| 
 | ||||
|     public componentWillUnmount() { | ||||
|         SettingsStore.unwatchSetting(this.groupFilterPanelWatcherRef); | ||||
|         BreadcrumbsStore.instance.off(UPDATE_EVENT, this.onBreadcrumbsUpdate); | ||||
|         RoomListStore.instance.off(LISTS_UPDATE_EVENT, this.onBreadcrumbsUpdate); | ||||
|         SpaceStore.instance.off(UPDATE_SELECTED_SPACE, this.updateActiveSpace); | ||||
|  | @ -422,16 +406,6 @@ export default class LeftPanel extends React.Component<IProps, IState> { | |||
|     } | ||||
| 
 | ||||
|     public render(): React.ReactNode { | ||||
|         let leftLeftPanel; | ||||
|         if (this.state.showGroupFilterPanel) { | ||||
|             leftLeftPanel = ( | ||||
|                 <div className="mx_LeftPanel_GroupFilterPanelContainer" ref={this.groupFilterPanelContainer}> | ||||
|                     <GroupFilterPanel /> | ||||
|                     { SettingsStore.getValue("feature_custom_tags") ? <CustomRoomTagPanel /> : null } | ||||
|                 </div> | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         const roomList = <RoomList | ||||
|             onKeyDown={this.onKeyDown} | ||||
|             resizeNotifier={this.props.resizeNotifier} | ||||
|  | @ -455,7 +429,6 @@ export default class LeftPanel extends React.Component<IProps, IState> { | |||
| 
 | ||||
|         return ( | ||||
|             <div className={containerClasses} ref={this.ref}> | ||||
|                 { leftLeftPanel } | ||||
|                 <aside className="mx_LeftPanel_roomListContainer"> | ||||
|                     { this.renderHeader() } | ||||
|                     { this.renderSearchDialExplore() } | ||||
|  |  | |||
|  | @ -68,6 +68,8 @@ import GroupView from "./GroupView"; | |||
| import BackdropPanel from "./BackdropPanel"; | ||||
| import SpaceStore from "../../stores/SpaceStore"; | ||||
| import classNames from 'classnames'; | ||||
| import GroupFilterPanel from './GroupFilterPanel'; | ||||
| import CustomRoomTagPanel from './CustomRoomTagPanel'; | ||||
| 
 | ||||
| // We need to fetch each pinned message individually (if we don't already have it)
 | ||||
| // so each pinned message may trigger a request. Limit the number per room for sanity.
 | ||||
|  | @ -131,7 +133,7 @@ interface IState { | |||
|     usageLimitEventTs?: number; | ||||
|     useCompactLayout: boolean; | ||||
|     activeCalls: Array<MatrixCall>; | ||||
|     backgroundImage?: CanvasImageSource; | ||||
|     backgroundImage?: string; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  | @ -222,7 +224,7 @@ class LoggedInView extends React.Component<IProps, IState> { | |||
| 
 | ||||
|     private refreshBackgroundImage = async (): Promise<void> => { | ||||
|         this.setState({ | ||||
|             backgroundImage: await OwnProfileStore.instance.getAvatarBitmap(), | ||||
|             backgroundImage: OwnProfileStore.instance.getHttpAvatarUrl(), | ||||
|         }); | ||||
|     }; | ||||
| 
 | ||||
|  | @ -289,7 +291,7 @@ class LoggedInView extends React.Component<IProps, IState> { | |||
|         if (isNaN(lhsSize)) { | ||||
|             lhsSize = 350; | ||||
|         } | ||||
|         this.resizer.forHandleAt(0).resize(lhsSize); | ||||
|         this.resizer.forHandleWithId('lp-resizer').resize(lhsSize); | ||||
|     } | ||||
| 
 | ||||
|     private onAccountData = (event: MatrixEvent) => { | ||||
|  | @ -653,16 +655,37 @@ class LoggedInView extends React.Component<IProps, IState> { | |||
|                 > | ||||
|                     <ToastContainer /> | ||||
|                     <div className={bodyClasses}> | ||||
|                         <div ref={this._resizeContainer} className='mx_LeftPanel_wrapper'> | ||||
|                         <div className='mx_LeftPanel_wrapper'> | ||||
|                             { SettingsStore.getValue('TagPanel.enableTagPanel') && | ||||
|                                 (<div className="mx_GroupFilterPanelContainer"> | ||||
|                                     <BackdropPanel | ||||
|                                         blurMultiplier={0.5} | ||||
|                                         backgroundImage={this.state.backgroundImage} | ||||
|                                     /> | ||||
|                                     <GroupFilterPanel /> | ||||
|                                     { SettingsStore.getValue("feature_custom_tags") ? <CustomRoomTagPanel /> : null } | ||||
|                                 </div>) | ||||
|                             } | ||||
|                             { SpaceStore.spacesEnabled ? <> | ||||
|                                 <BackdropPanel | ||||
|                                     blurMultiplier={0.5} | ||||
|                                     backgroundImage={this.state.backgroundImage} | ||||
|                                 /> | ||||
|                                 <SpacePanel /> | ||||
|                             </> : null } | ||||
|                             <BackdropPanel | ||||
|                                 backgroundImage={this.state.backgroundImage} | ||||
|                             /> | ||||
|                             { SpaceStore.spacesEnabled ? <SpacePanel /> : null } | ||||
|                             <LeftPanel | ||||
|                                 isMinimized={this.props.collapseLhs || false} | ||||
|                                 resizeNotifier={this.props.resizeNotifier} | ||||
|                             /> | ||||
|                             <ResizeHandle /> | ||||
|                             <div | ||||
|                                 ref={this._resizeContainer} | ||||
|                                 className="mx_LeftPanel_wrapper--user" | ||||
|                             > | ||||
|                                 <LeftPanel | ||||
|                                     isMinimized={this.props.collapseLhs || false} | ||||
|                                     resizeNotifier={this.props.resizeNotifier} | ||||
|                                 /> | ||||
|                                 <ResizeHandle id="lp-resizer" /> | ||||
|                             </div> | ||||
|                         </div> | ||||
|                         <div className="mx_RoomView_wrapper"> | ||||
|                             { pageElement } | ||||
|  |  | |||
|  | @ -182,8 +182,6 @@ export default class Resizer<C extends IConfig = IConfig> { | |||
| 
 | ||||
|     private getResizeHandles() { | ||||
|         if (!this.container.children) return []; | ||||
|         return Array.from(this.container.children).filter(el => { | ||||
|             return this.isResizeHandle(<HTMLElement>el); | ||||
|         }) as HTMLElement[]; | ||||
|         return Array.from(this.container.querySelectorAll(`.${this.classNames.handle}`)) as HTMLElement[]; | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -19,12 +19,10 @@ import { AsyncStoreWithClient } from "./AsyncStoreWithClient"; | |||
| import defaultDispatcher from "../dispatcher/dispatcher"; | ||||
| import { MatrixEvent } from "matrix-js-sdk/src/models/event"; | ||||
| import { User } from "matrix-js-sdk/src/models/user"; | ||||
| import { memoize, throttle } from "lodash"; | ||||
| import { throttle } from "lodash"; | ||||
| import { MatrixClientPeg } from "../MatrixClientPeg"; | ||||
| import { _t } from "../languageHandler"; | ||||
| import { mediaFromMxc } from "../customisations/Media"; | ||||
| import SettingsStore from "../settings/SettingsStore"; | ||||
| import { getDrawable } from "../utils/drawable"; | ||||
| 
 | ||||
| interface IState { | ||||
|     displayName?: string; | ||||
|  | @ -139,22 +137,6 @@ export class OwnProfileStore extends AsyncStoreWithClient<IState> { | |||
|         await this.updateState({ displayName: profileInfo.displayname, avatarUrl: profileInfo.avatar_url }); | ||||
|     }; | ||||
| 
 | ||||
|     public async getAvatarBitmap(avatarSize = 32): Promise<CanvasImageSource> { | ||||
|         let avatarUrl = this.getHttpAvatarUrl(avatarSize); | ||||
|         const settingBgMxc = SettingsStore.getValue("RoomList.backgroundImage"); | ||||
|         if (settingBgMxc) { | ||||
|             avatarUrl = mediaFromMxc(settingBgMxc).getSquareThumbnailHttp(avatarSize); | ||||
|         } | ||||
| 
 | ||||
|         if (avatarUrl) { | ||||
|             return await this.buildBitmap(avatarUrl); | ||||
|         } else { | ||||
|             return null; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private buildBitmap = memoize(getDrawable); | ||||
| 
 | ||||
|     private onStateEvents = throttle(async (ev: MatrixEvent) => { | ||||
|         const myUserId = MatrixClientPeg.get().getUserId(); | ||||
|         if (ev.getType() === 'm.room.member' && ev.getSender() === myUserId && ev.getStateKey() === myUserId) { | ||||
|  |  | |||
|  | @ -2917,11 +2917,6 @@ content-type@^1.0.4: | |||
|   resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" | ||||
|   integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== | ||||
| 
 | ||||
| context-filter-polyfill@^0.2.4: | ||||
|   version "0.2.4" | ||||
|   resolved "https://registry.yarnpkg.com/context-filter-polyfill/-/context-filter-polyfill-0.2.4.tgz#ecf88d3197e7c3a47e9a7ae2d5167b703945a5d4" | ||||
|   integrity sha512-LDZ3WiTzo6kIeJM7j8kPSgZf+gbD1cV1GaLyYO8RWvAg25cO3zUo3d2KizO0w9hAezNwz7tTbuWKpPdvLWzKqQ== | ||||
| 
 | ||||
| convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: | ||||
|   version "1.8.0" | ||||
|   resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Dariusz Niemczyk
						Dariusz Niemczyk