Merge branch 'develop' into gsouquet/message-bubbles-4635

This commit is contained in:
Germain Souquet 2021-07-07 13:07:43 +02:00
commit 10bdb3cefa
148 changed files with 2580 additions and 2149 deletions

View file

@ -0,0 +1,56 @@
/*
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 { decode } from "blurhash";
interface IProps {
blurhash: string;
width: number;
height: number;
}
export default class BlurhashPlaceholder extends React.PureComponent<IProps> {
private canvas: React.RefObject<HTMLCanvasElement> = React.createRef();
public componentDidMount() {
this.draw();
}
public componentDidUpdate() {
this.draw();
}
private draw() {
if (!this.canvas.current) return;
try {
const { width, height } = this.props;
const pixels = decode(this.props.blurhash, Math.ceil(width), Math.ceil(height));
const ctx = this.canvas.current.getContext("2d");
const imgData = ctx.createImageData(width, height);
imgData.data.set(pixels);
ctx.putImageData(imgData, 0, 0);
} catch (e) {
console.error("Error rendering blurhash: ", e);
}
}
public render() {
return <canvas height={this.props.height} width={this.props.width} ref={this.canvas} />;
}
}

View file

@ -29,7 +29,7 @@ interface IProps {
// The minimum number of events needed to trigger summarisation
threshold?: number;
// Whether or not to begin with state.expanded=true
startExpanded?: boolean,
startExpanded?: boolean;
// The list of room members for which to show avatars next to the summary
summaryMembers?: RoomMember[];
// The text to show as the summary of this event list

View file

@ -24,7 +24,7 @@ import FocusLock from "react-focus-lock";
import MemberAvatar from "../avatars/MemberAvatar";
import { ContextMenuTooltipButton } from "../../../accessibility/context_menu/ContextMenuTooltipButton";
import MessageContextMenu from "../context_menus/MessageContextMenu";
import { aboveLeftOf, ContextMenu } from '../../structures/ContextMenu';
import { aboveLeftOf } from '../../structures/ContextMenu';
import MessageTimestamp from "../messages/MessageTimestamp";
import SettingsStore from "../../../settings/SettingsStore";
import { formatFullDate } from "../../../DateUtils";
@ -44,31 +44,31 @@ const ZOOM_COEFFICIENT = 0.0025;
const ZOOM_DISTANCE = 10;
interface IProps {
src: string, // the source of the image being displayed
name?: string, // the main title ('name') for the image
link?: string, // the link (if any) applied to the name of the image
width?: number, // width of the image src in pixels
height?: number, // height of the image src in pixels
fileSize?: number, // size of the image src in bytes
onFinished(): void, // callback when the lightbox is dismissed
src: string; // the source of the image being displayed
name?: string; // the main title ('name') for the image
link?: string; // the link (if any) applied to the name of the image
width?: number; // width of the image src in pixels
height?: number; // height of the image src in pixels
fileSize?: number; // size of the image src in bytes
onFinished(): void; // callback when the lightbox is dismissed
// the event (if any) that the Image is displaying. Used for event-specific stuff like
// redactions, senders, timestamps etc. Other descriptors are taken from the explicit
// properties above, which let us use lightboxes to display images which aren't associated
// with events.
mxEvent: MatrixEvent,
permalinkCreator: RoomPermalinkCreator,
mxEvent: MatrixEvent;
permalinkCreator: RoomPermalinkCreator;
}
interface IState {
zoom: number,
minZoom: number,
maxZoom: number,
rotation: number,
translationX: number,
translationY: number,
moving: boolean,
contextMenuDisplayed: boolean,
zoom: number;
minZoom: number;
maxZoom: number;
rotation: number;
translationX: number;
translationY: number;
moving: boolean;
contextMenuDisplayed: boolean;
}
@replaceableComponent("views.elements.ImageView")
@ -122,7 +122,7 @@ export default class ImageView extends React.Component<IProps, IState> {
const image = this.image.current;
const imageWrapper = this.imageWrapper.current;
const rotation = inputRotation || this.state.rotation;
const rotation = inputRotation ?? this.state.rotation;
const imageIsNotFlipped = rotation % 180 === 0;
@ -304,17 +304,13 @@ export default class ImageView extends React.Component<IProps, IState> {
let contextMenu = null;
if (this.state.contextMenuDisplayed) {
contextMenu = (
<ContextMenu
<MessageContextMenu
{...aboveLeftOf(this.contextMenuButton.current.getBoundingClientRect())}
mxEvent={this.props.mxEvent}
permalinkCreator={this.props.permalinkCreator}
onFinished={this.onCloseContextMenu}
>
<MessageContextMenu
mxEvent={this.props.mxEvent}
permalinkCreator={this.props.permalinkCreator}
onFinished={this.onCloseContextMenu}
onCloseDialog={this.props.onFinished}
/>
</ContextMenu>
onCloseDialog={this.props.onFinished}
/>
);
}

View file

@ -30,14 +30,14 @@ function languageMatchesSearchQuery(query, language) {
}
interface SpellCheckLanguagesDropdownIProps {
className: string,
value: string,
onOptionChange(language: string),
className: string;
value: string;
onOptionChange(language: string);
}
interface SpellCheckLanguagesDropdownIState {
searchQuery: string,
languages: any,
searchQuery: string;
languages: any;
}
@replaceableComponent("views.elements.SpellCheckLanguagesDropdown")