Merge branch 'joriks/font-scaling-message-preview' into joriks/appearance-tab-layout-options
This commit is contained in:
commit
f2440388b1
102 changed files with 1705 additions and 748 deletions
|
@ -19,7 +19,7 @@ import React from 'react';
|
|||
import {Key} from '../../../Keyboard';
|
||||
import classnames from 'classnames';
|
||||
|
||||
export type ButtonEvent = React.MouseEvent<Element> | React.KeyboardEvent<Element>
|
||||
export type ButtonEvent = React.MouseEvent<Element> | React.KeyboardEvent<Element>;
|
||||
|
||||
/**
|
||||
* children: React's magic prop. Represents all children given to the element.
|
||||
|
@ -40,7 +40,7 @@ interface IProps extends React.InputHTMLAttributes<Element> {
|
|||
disabled?: boolean;
|
||||
className?: string;
|
||||
onClick?(e?: ButtonEvent): void;
|
||||
};
|
||||
}
|
||||
|
||||
interface IAccessibleButtonProps extends React.InputHTMLAttributes<Element> {
|
||||
ref?: React.Ref<Element>;
|
||||
|
|
|
@ -17,20 +17,20 @@ limitations under the License.
|
|||
import React from 'react';
|
||||
|
||||
interface IProps {
|
||||
className: string,
|
||||
dragFunc: (currentLocation: ILocationState, event: MouseEvent) => ILocationState,
|
||||
onMouseUp: (event: MouseEvent) => void,
|
||||
className: string;
|
||||
dragFunc: (currentLocation: ILocationState, event: MouseEvent) => ILocationState;
|
||||
onMouseUp: (event: MouseEvent) => void;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
onMouseMove: (event: MouseEvent) => void,
|
||||
onMouseUp: (event: MouseEvent) => void,
|
||||
location: ILocationState,
|
||||
onMouseMove: (event: MouseEvent) => void;
|
||||
onMouseUp: (event: MouseEvent) => void;
|
||||
location: ILocationState;
|
||||
}
|
||||
|
||||
export interface ILocationState {
|
||||
currentX: number,
|
||||
currentY: number,
|
||||
currentX: number;
|
||||
currentY: number;
|
||||
}
|
||||
|
||||
export default class Draggable extends React.Component<IProps, IState> {
|
||||
|
@ -58,13 +58,13 @@ export default class Draggable extends React.Component<IProps, IState> {
|
|||
|
||||
document.addEventListener("mousemove", this.state.onMouseMove);
|
||||
document.addEventListener("mouseup", this.state.onMouseUp);
|
||||
}
|
||||
};
|
||||
|
||||
private onMouseUp = (event: MouseEvent): void => {
|
||||
document.removeEventListener("mousemove", this.state.onMouseMove);
|
||||
document.removeEventListener("mouseup", this.state.onMouseUp);
|
||||
this.props.onMouseUp(event);
|
||||
}
|
||||
};
|
||||
|
||||
private onMouseMove(event: MouseEvent): void {
|
||||
const newLocation = this.props.dragFunc(this.state.location, event);
|
||||
|
@ -75,7 +75,7 @@ export default class Draggable extends React.Component<IProps, IState> {
|
|||
}
|
||||
|
||||
render() {
|
||||
return <div className={this.props.className} onMouseDown={this.onMouseDown.bind(this)} />
|
||||
return <div className={this.props.className} onMouseDown={this.onMouseDown.bind(this)} />;
|
||||
}
|
||||
|
||||
}
|
|
@ -47,7 +47,7 @@ interface IState {
|
|||
|
||||
const AVATAR_SIZE = 32;
|
||||
|
||||
export default class MessagePreview extends React.Component<IProps, IState> {
|
||||
export default class EventTilePreview extends React.Component<IProps, IState> {
|
||||
constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
|
@ -55,14 +55,13 @@ export default class MessagePreview extends React.Component<IProps, IState> {
|
|||
userId: "@erim:fink.fink",
|
||||
displayname: "Erimayas Fink",
|
||||
avatar_url: null,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
// Fetch current user data
|
||||
const client = MatrixClientPeg.get()
|
||||
const client = MatrixClientPeg.get();
|
||||
const userId = client.getUserId();
|
||||
console.log({userId})
|
||||
const profileInfo = await client.getProfileInfo(userId);
|
||||
const avatar_url = Avatar.avatarUrlForUser(
|
||||
{avatarUrl: profileInfo.avatar_url},
|
||||
|
@ -98,7 +97,7 @@ export default class MessagePreview extends React.Component<IProps, IState> {
|
|||
},
|
||||
"event_id": "$9999999999999999999999999999999999999999999",
|
||||
"room_id": "!999999999999999999:matrix.org"
|
||||
}`))
|
||||
}`));
|
||||
|
||||
// Fake it more
|
||||
event.sender = {
|
||||
|
@ -107,7 +106,7 @@ export default class MessagePreview extends React.Component<IProps, IState> {
|
|||
getAvatarUrl: (..._) => {
|
||||
return avatar_url;
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
@ -125,6 +124,6 @@ export default class MessagePreview extends React.Component<IProps, IState> {
|
|||
|
||||
return <div className={className}>
|
||||
<EventTile mxEvent={event} useIRCLayout={this.props.useIRCLayout} />
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
}
|
|
@ -14,11 +14,11 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, {InputHTMLAttributes, SelectHTMLAttributes, TextareaHTMLAttributes} from 'react';
|
||||
import classNames from 'classnames';
|
||||
import * as sdk from '../../../index';
|
||||
import { debounce } from 'lodash';
|
||||
import {IFieldState, IValidationResult} from "../elements/Validation";
|
||||
import {IFieldState, IValidationResult} from "./Validation";
|
||||
|
||||
// Invoke validation from user input (when typing, etc.) at most once every N ms.
|
||||
const VALIDATION_THROTTLE_MS = 200;
|
||||
|
@ -29,60 +29,76 @@ function getId() {
|
|||
return `${BASE_ID}_${count++}`;
|
||||
}
|
||||
|
||||
interface IProps extends React.InputHTMLAttributes<HTMLSelectElement | HTMLInputElement> {
|
||||
interface IProps {
|
||||
// The field's ID, which binds the input and label together. Immutable.
|
||||
id?: string,
|
||||
// The element to create. Defaults to "input".
|
||||
// To define options for a select, use <Field><option ... /></Field>
|
||||
element?: "input" | "select" | "textarea",
|
||||
id?: string;
|
||||
// The field's type (when used as an <input>). Defaults to "text".
|
||||
type?: string,
|
||||
type?: string;
|
||||
// id of a <datalist> element for suggestions
|
||||
list?: string,
|
||||
list?: string;
|
||||
// The field's label string.
|
||||
label?: string,
|
||||
label?: string;
|
||||
// The field's placeholder string. Defaults to the label.
|
||||
placeholder?: string,
|
||||
// The field's value.
|
||||
// This is a controlled component, so the value is required.
|
||||
value: string,
|
||||
placeholder?: string;
|
||||
// Optional component to include inside the field before the input.
|
||||
prefixComponent?: React.ReactNode,
|
||||
prefixComponent?: React.ReactNode;
|
||||
// Optional component to include inside the field after the input.
|
||||
postfixComponent?: React.ReactNode,
|
||||
postfixComponent?: React.ReactNode;
|
||||
// The callback called whenever the contents of the field
|
||||
// changes. Returns an object with `valid` boolean field
|
||||
// and a `feedback` react component field to provide feedback
|
||||
// to the user.
|
||||
onValidate?: (input: IFieldState) => Promise<IValidationResult>,
|
||||
onValidate?: (input: IFieldState) => Promise<IValidationResult>;
|
||||
// If specified, overrides the value returned by onValidate.
|
||||
flagInvalid?: boolean,
|
||||
flagInvalid?: boolean;
|
||||
// If specified, contents will appear as a tooltip on the element and
|
||||
// validation feedback tooltips will be suppressed.
|
||||
tooltipContent?: React.ReactNode,
|
||||
tooltipContent?: React.ReactNode;
|
||||
// If specified alongside tooltipContent, the class name to apply to the
|
||||
// tooltip itself.
|
||||
tooltipClassName?: string,
|
||||
tooltipClassName?: string;
|
||||
// If specified, an additional class name to apply to the field container
|
||||
className?: string,
|
||||
className?: string;
|
||||
// All other props pass through to the <input>.
|
||||
}
|
||||
|
||||
interface IState {
|
||||
valid: boolean,
|
||||
feedback: React.ReactNode,
|
||||
feedbackVisible: boolean,
|
||||
focused: boolean,
|
||||
interface IInputProps extends IProps, InputHTMLAttributes<HTMLInputElement> {
|
||||
// The element to create. Defaults to "input".
|
||||
element?: "input";
|
||||
// The input's value. This is a controlled component, so the value is required.
|
||||
value: string;
|
||||
}
|
||||
|
||||
export default class Field extends React.PureComponent<IProps, IState> {
|
||||
interface ISelectProps extends IProps, SelectHTMLAttributes<HTMLSelectElement> {
|
||||
// To define options for a select, use <Field><option ... /></Field>
|
||||
element: "select";
|
||||
// The select's value. This is a controlled component, so the value is required.
|
||||
value: string;
|
||||
}
|
||||
|
||||
interface ITextareaProps extends IProps, TextareaHTMLAttributes<HTMLTextAreaElement> {
|
||||
element: "textarea";
|
||||
// The textarea's value. This is a controlled component, so the value is required.
|
||||
value: string;
|
||||
}
|
||||
|
||||
type PropShapes = IInputProps | ISelectProps | ITextareaProps;
|
||||
|
||||
interface IState {
|
||||
valid: boolean;
|
||||
feedback: React.ReactNode;
|
||||
feedbackVisible: boolean;
|
||||
focused: boolean;
|
||||
}
|
||||
|
||||
export default class Field extends React.PureComponent<PropShapes, IState> {
|
||||
private id: string;
|
||||
private input: HTMLInputElement;
|
||||
|
||||
private static defaultProps = {
|
||||
public static readonly defaultProps = {
|
||||
element: "input",
|
||||
type: "text",
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* This was changed from throttle to debounce: this is more traditional for
|
||||
|
|
|
@ -20,15 +20,15 @@ import Draggable, {ILocationState} from './Draggable';
|
|||
|
||||
interface IProps {
|
||||
// Current room
|
||||
roomId: string,
|
||||
minWidth: number,
|
||||
maxWidth: number,
|
||||
};
|
||||
roomId: string;
|
||||
minWidth: number;
|
||||
maxWidth: number;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
width: number,
|
||||
IRCLayoutRoot: HTMLElement,
|
||||
};
|
||||
width: number;
|
||||
IRCLayoutRoot: HTMLElement;
|
||||
}
|
||||
|
||||
export default class IRCTimelineProfileResizer extends React.Component<IProps, IState> {
|
||||
constructor(props: IProps) {
|
||||
|
@ -37,20 +37,19 @@ export default class IRCTimelineProfileResizer extends React.Component<IProps, I
|
|||
this.state = {
|
||||
width: SettingsStore.getValue("ircDisplayNameWidth", this.props.roomId),
|
||||
IRCLayoutRoot: null,
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.setState({
|
||||
IRCLayoutRoot: document.querySelector(".mx_IRCLayout") as HTMLElement,
|
||||
}, () => this.updateCSSWidth(this.state.width))
|
||||
}, () => this.updateCSSWidth(this.state.width));
|
||||
}
|
||||
|
||||
private dragFunc = (location: ILocationState, event: React.MouseEvent<Element, MouseEvent>): ILocationState => {
|
||||
const offset = event.clientX - location.currentX;
|
||||
const newWidth = this.state.width + offset;
|
||||
|
||||
console.log({offset})
|
||||
// If we're trying to go smaller than min width, don't.
|
||||
if (newWidth < this.props.minWidth) {
|
||||
return location;
|
||||
|
@ -69,8 +68,8 @@ export default class IRCTimelineProfileResizer extends React.Component<IProps, I
|
|||
return {
|
||||
currentX: event.clientX,
|
||||
currentY: location.currentY,
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
private updateCSSWidth(newWidth: number) {
|
||||
this.state.IRCLayoutRoot.style.setProperty("--name-width", newWidth + "px");
|
||||
|
@ -83,6 +82,10 @@ export default class IRCTimelineProfileResizer extends React.Component<IProps, I
|
|||
}
|
||||
|
||||
render() {
|
||||
return <Draggable className="mx_ProfileResizer" dragFunc={this.dragFunc.bind(this)} onMouseUp={this.onMoueUp.bind(this)}/>
|
||||
return <Draggable
|
||||
className="mx_ProfileResizer"
|
||||
dragFunc={this.dragFunc.bind(this)}
|
||||
onMouseUp={this.onMoueUp.bind(this)}
|
||||
/>;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -48,18 +48,18 @@ export default class SettingsFlag extends React.Component<IProps, IState> {
|
|||
this.props.roomId,
|
||||
this.props.isExplicit,
|
||||
),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private onChange = (checked: boolean): void => {
|
||||
this.save(checked);
|
||||
this.setState({ value: checked });
|
||||
if (this.props.onChange) this.props.onChange(checked);
|
||||
}
|
||||
};
|
||||
|
||||
private checkBoxOnChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
this.onChange(e.target.checked);
|
||||
}
|
||||
};
|
||||
|
||||
private save = (val?: boolean): void => {
|
||||
return SettingsStore.setValue(
|
||||
|
@ -68,7 +68,7 @@ export default class SettingsFlag extends React.Component<IProps, IState> {
|
|||
this.props.level,
|
||||
val !== undefined ? val : this.state.value,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
public render() {
|
||||
const canChange = SettingsStore.canSetValue(this.props.name, this.props.roomId, this.props.level);
|
||||
|
|
|
@ -65,9 +65,9 @@ export default class Slider extends React.Component<IProps> {
|
|||
|
||||
const intervalWidth = 1 / (values.length - 1);
|
||||
|
||||
const linearInterpolation = (value - closestLessValue) / (closestGreaterValue - closestLessValue)
|
||||
const linearInterpolation = (value - closestLessValue) / (closestGreaterValue - closestLessValue);
|
||||
|
||||
return 100 * (closest - 1 + linearInterpolation) * intervalWidth
|
||||
return 100 * (closest - 1 + linearInterpolation) * intervalWidth;
|
||||
|
||||
}
|
||||
|
||||
|
@ -87,7 +87,7 @@ export default class Slider extends React.Component<IProps> {
|
|||
selection = <div className="mx_Slider_selection">
|
||||
<div className="mx_Slider_selectionDot" style={{left: "calc(-0.55em + " + offset + "%)"}} />
|
||||
<hr style={{width: offset + "%"}} />
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
|
||||
return <div className="mx_Slider">
|
||||
|
@ -115,13 +115,13 @@ export default class Slider extends React.Component<IProps> {
|
|||
|
||||
interface IDotProps {
|
||||
// Callback for behavior onclick
|
||||
onClick: () => void,
|
||||
onClick: () => void;
|
||||
|
||||
// Whether the dot should appear active
|
||||
active: boolean,
|
||||
active: boolean;
|
||||
|
||||
// The label on the dot
|
||||
label: string,
|
||||
label: string;
|
||||
|
||||
// Whether the slider is disabled
|
||||
disabled: boolean;
|
||||
|
@ -129,7 +129,7 @@ interface IDotProps {
|
|||
|
||||
class Dot extends React.PureComponent<IDotProps> {
|
||||
render(): React.ReactNode {
|
||||
let className = "mx_Slider_dot"
|
||||
let className = "mx_Slider_dot";
|
||||
if (!this.props.disabled && this.props.active) {
|
||||
className += " mx_Slider_dotActive";
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ export default class StyledCheckbox extends React.PureComponent<IProps, IState>
|
|||
|
||||
public static readonly defaultProps = {
|
||||
className: "",
|
||||
}
|
||||
};
|
||||
|
||||
constructor(props: IProps) {
|
||||
super(props);
|
||||
|
@ -51,6 +51,6 @@ export default class StyledCheckbox extends React.PureComponent<IProps, IState>
|
|||
{ this.props.children }
|
||||
</div>
|
||||
</label>
|
||||
</span>
|
||||
</span>;
|
||||
}
|
||||
}
|
|
@ -26,7 +26,7 @@ interface IState {
|
|||
export default class StyledRadioButton extends React.PureComponent<IProps, IState> {
|
||||
public static readonly defaultProps = {
|
||||
className: '',
|
||||
}
|
||||
};
|
||||
|
||||
public render() {
|
||||
const { children, className, disabled, ...otherProps } = this.props;
|
||||
|
@ -44,6 +44,6 @@ export default class StyledRadioButton extends React.PureComponent<IProps, IStat
|
|||
<div><div></div></div>
|
||||
<span>{children}</span>
|
||||
<div className="mx_RadioButton_spacer" />
|
||||
</label>
|
||||
</label>;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ interface IProps {
|
|||
|
||||
// Called when the checked state changes. First argument will be the new state.
|
||||
onChange(checked: boolean): void;
|
||||
};
|
||||
}
|
||||
|
||||
// Controlled Toggle Switch element, written with Accessibility in mind
|
||||
export default ({checked, disabled = false, onChange, ...props}: IProps) => {
|
||||
|
|
|
@ -29,15 +29,15 @@ const MIN_TOOLTIP_HEIGHT = 25;
|
|||
|
||||
interface IProps {
|
||||
// Class applied to the element used to position the tooltip
|
||||
className: string,
|
||||
className: string;
|
||||
// Class applied to the tooltip itself
|
||||
tooltipClassName?: string,
|
||||
tooltipClassName?: string;
|
||||
// Whether the tooltip is visible or hidden.
|
||||
// The hidden state allows animating the tooltip away via CSS.
|
||||
// Defaults to visible if unset.
|
||||
visible?: boolean,
|
||||
visible?: boolean;
|
||||
// the react element to put into the tooltip
|
||||
label: React.ReactNode,
|
||||
label: React.ReactNode;
|
||||
}
|
||||
|
||||
export default class Tooltip extends React.Component<IProps> {
|
||||
|
@ -126,7 +126,7 @@ export default class Tooltip extends React.Component<IProps> {
|
|||
tooltip: this.tooltip,
|
||||
parent: parent,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
public render() {
|
||||
// Render a placeholder
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue