Merge pull request #5155 from matrix-org/t3chguy/lint-ts
Fix eslint ts override tsx matching and delint
This commit is contained in:
commit
7c4a84aae0
54 changed files with 257 additions and 242 deletions
|
@ -19,7 +19,7 @@ module.exports = {
|
||||||
},
|
},
|
||||||
|
|
||||||
overrides: [{
|
overrides: [{
|
||||||
"files": ["src/**/*.{ts, tsx}"],
|
"files": ["src/**/*.{ts,tsx}"],
|
||||||
"extends": ["matrix-org/ts"],
|
"extends": ["matrix-org/ts"],
|
||||||
"rules": {
|
"rules": {
|
||||||
// We disable this while we're transitioning
|
// We disable this while we're transitioning
|
||||||
|
|
|
@ -70,6 +70,7 @@ interface IContent {
|
||||||
|
|
||||||
interface IThumbnail {
|
interface IThumbnail {
|
||||||
info: {
|
info: {
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
thumbnail_info: {
|
thumbnail_info: {
|
||||||
w: number;
|
w: number;
|
||||||
h: number;
|
h: number;
|
||||||
|
@ -104,7 +105,12 @@ interface IAbortablePromise<T> extends Promise<T> {
|
||||||
* @return {Promise} A promise that resolves with an object with an info key
|
* @return {Promise} A promise that resolves with an object with an info key
|
||||||
* and a thumbnail key.
|
* and a thumbnail key.
|
||||||
*/
|
*/
|
||||||
function createThumbnail(element: ThumbnailableElement, inputWidth: number, inputHeight: number, mimeType: string): Promise<IThumbnail> {
|
function createThumbnail(
|
||||||
|
element: ThumbnailableElement,
|
||||||
|
inputWidth: number,
|
||||||
|
inputHeight: number,
|
||||||
|
mimeType: string,
|
||||||
|
): Promise<IThumbnail> {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
let targetWidth = inputWidth;
|
let targetWidth = inputWidth;
|
||||||
let targetHeight = inputHeight;
|
let targetHeight = inputHeight;
|
||||||
|
@ -437,11 +443,13 @@ export default class ContentMessages {
|
||||||
for (let i = 0; i < okFiles.length; ++i) {
|
for (let i = 0; i < okFiles.length; ++i) {
|
||||||
const file = okFiles[i];
|
const file = okFiles[i];
|
||||||
if (!uploadAll) {
|
if (!uploadAll) {
|
||||||
const {finished} = Modal.createTrackedDialog<[boolean, boolean]>('Upload Files confirmation', '', UploadConfirmDialog, {
|
const {finished} = Modal.createTrackedDialog<[boolean, boolean]>('Upload Files confirmation',
|
||||||
file,
|
'', UploadConfirmDialog, {
|
||||||
currentIndex: i,
|
file,
|
||||||
totalFiles: okFiles.length,
|
currentIndex: i,
|
||||||
});
|
totalFiles: okFiles.length,
|
||||||
|
},
|
||||||
|
);
|
||||||
const [shouldContinue, shouldUploadAll] = await finished;
|
const [shouldContinue, shouldUploadAll] = await finished;
|
||||||
if (!shouldContinue) break;
|
if (!shouldContinue) break;
|
||||||
if (shouldUploadAll) {
|
if (shouldUploadAll) {
|
||||||
|
|
|
@ -339,33 +339,9 @@ class HtmlHighlighter extends BaseHighlighter<string> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TextHighlighter extends BaseHighlighter<React.ReactNode> {
|
|
||||||
private key = 0;
|
|
||||||
|
|
||||||
/* create a <span> node to hold the given content
|
|
||||||
*
|
|
||||||
* snippet: content of the span
|
|
||||||
* highlight: true to highlight as a search match
|
|
||||||
*
|
|
||||||
* returns a React node
|
|
||||||
*/
|
|
||||||
protected processSnippet(snippet: string, highlight: boolean): React.ReactNode {
|
|
||||||
const key = this.key++;
|
|
||||||
|
|
||||||
let node = <span key={key} className={highlight ? this.highlightClass : null}>
|
|
||||||
{ snippet }
|
|
||||||
</span>;
|
|
||||||
|
|
||||||
if (highlight && this.highlightLink) {
|
|
||||||
node = <a key={key} href={this.highlightLink}>{ node }</a>;
|
|
||||||
}
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IContent {
|
interface IContent {
|
||||||
format?: string;
|
format?: string;
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
formatted_body?: string;
|
formatted_body?: string;
|
||||||
body: string;
|
body: string;
|
||||||
}
|
}
|
||||||
|
@ -474,8 +450,13 @@ export function bodyToHtml(content: IContent, highlights: string[], opts: IOpts
|
||||||
});
|
});
|
||||||
|
|
||||||
return isDisplayedWithHtml ?
|
return isDisplayedWithHtml ?
|
||||||
<span key="body" ref={opts.ref} className={className} dangerouslySetInnerHTML={{ __html: safeBody }} dir="auto" /> :
|
<span
|
||||||
<span key="body" ref={opts.ref} className={className} dir="auto">{ strippedBody }</span>;
|
key="body"
|
||||||
|
ref={opts.ref}
|
||||||
|
className={className}
|
||||||
|
dangerouslySetInnerHTML={{ __html: safeBody }}
|
||||||
|
dir="auto"
|
||||||
|
/> : <span key="body" ref={opts.ref} className={className} dir="auto">{ strippedBody }</span>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -151,7 +151,7 @@ export class ModalManager {
|
||||||
prom: Promise<React.ComponentType>,
|
prom: Promise<React.ComponentType>,
|
||||||
props?: IProps<T>,
|
props?: IProps<T>,
|
||||||
className?: string,
|
className?: string,
|
||||||
options?: IOptions<T>
|
options?: IOptions<T>,
|
||||||
) {
|
) {
|
||||||
const modal: IModal<T> = {
|
const modal: IModal<T> = {
|
||||||
onFinished: props ? props.onFinished : null,
|
onFinished: props ? props.onFinished : null,
|
||||||
|
@ -182,7 +182,7 @@ export class ModalManager {
|
||||||
|
|
||||||
private getCloseFn<T extends any[]>(
|
private getCloseFn<T extends any[]>(
|
||||||
modal: IModal<T>,
|
modal: IModal<T>,
|
||||||
props: IProps<T>
|
props: IProps<T>,
|
||||||
): [IHandle<T>["close"], IHandle<T>["finished"]] {
|
): [IHandle<T>["close"], IHandle<T>["finished"]] {
|
||||||
const deferred = defer<T>();
|
const deferred = defer<T>();
|
||||||
return [async (...args: T) => {
|
return [async (...args: T) => {
|
||||||
|
@ -264,7 +264,7 @@ export class ModalManager {
|
||||||
className?: string,
|
className?: string,
|
||||||
isPriorityModal = false,
|
isPriorityModal = false,
|
||||||
isStaticModal = false,
|
isStaticModal = false,
|
||||||
options: IOptions<T> = {}
|
options: IOptions<T> = {},
|
||||||
): IHandle<T> {
|
): IHandle<T> {
|
||||||
const {modal, closeDialog, onFinishedProm} = this.buildModal<T>(prom, props, className, options);
|
const {modal, closeDialog, onFinishedProm} = this.buildModal<T>(prom, props, className, options);
|
||||||
if (isPriorityModal) {
|
if (isPriorityModal) {
|
||||||
|
@ -287,7 +287,7 @@ export class ModalManager {
|
||||||
private appendDialogAsync<T extends any[]>(
|
private appendDialogAsync<T extends any[]>(
|
||||||
prom: Promise<React.ComponentType>,
|
prom: Promise<React.ComponentType>,
|
||||||
props?: IProps<T>,
|
props?: IProps<T>,
|
||||||
className?: string
|
className?: string,
|
||||||
): IHandle<T> {
|
): IHandle<T> {
|
||||||
const {modal, closeDialog, onFinishedProm} = this.buildModal<T>(prom, props, className, {});
|
const {modal, closeDialog, onFinishedProm} = this.buildModal<T>(prom, props, className, {});
|
||||||
|
|
||||||
|
|
|
@ -860,12 +860,12 @@ export const Commands = [
|
||||||
_t('WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and session' +
|
_t('WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and session' +
|
||||||
' %(deviceId)s is "%(fprint)s" which does not match the provided key ' +
|
' %(deviceId)s is "%(fprint)s" which does not match the provided key ' +
|
||||||
'"%(fingerprint)s". This could mean your communications are being intercepted!',
|
'"%(fingerprint)s". This could mean your communications are being intercepted!',
|
||||||
{
|
{
|
||||||
fprint,
|
fprint,
|
||||||
userId,
|
userId,
|
||||||
deviceId,
|
deviceId,
|
||||||
fingerprint,
|
fingerprint,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
await cli.setDeviceVerified(userId, deviceId, true);
|
await cli.setDeviceVerified(userId, deviceId, true);
|
||||||
|
@ -879,7 +879,7 @@ export const Commands = [
|
||||||
{
|
{
|
||||||
_t('The signing key you provided matches the signing key you received ' +
|
_t('The signing key you provided matches the signing key you received ' +
|
||||||
'from %(userId)s\'s session %(deviceId)s. Session marked as verified.',
|
'from %(userId)s\'s session %(deviceId)s. Session marked as verified.',
|
||||||
{userId, deviceId})
|
{userId, deviceId})
|
||||||
}
|
}
|
||||||
</p>
|
</p>
|
||||||
</div>,
|
</div>,
|
||||||
|
|
|
@ -168,7 +168,7 @@ const shortcuts: Record<Categories, IShortcut[]> = {
|
||||||
key: Key.U,
|
key: Key.U,
|
||||||
}],
|
}],
|
||||||
description: _td("Upload a file"),
|
description: _td("Upload a file"),
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
[Categories.ROOM_LIST]: [
|
[Categories.ROOM_LIST]: [
|
||||||
|
|
|
@ -190,7 +190,7 @@ export const RovingTabIndexProvider: React.FC<IProps> = ({children, handleHomeEn
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
} else if (onKeyDown) {
|
} else if (onKeyDown) {
|
||||||
return onKeyDown(ev, state);
|
return onKeyDown(ev, context.state);
|
||||||
}
|
}
|
||||||
}, [context.state, onKeyDown, handleHomeEnd]);
|
}, [context.state, onKeyDown, handleHomeEnd]);
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ const Toolbar: React.FC<IProps> = ({children, ...props}) => {
|
||||||
const target = ev.target as HTMLElement;
|
const target = ev.target as HTMLElement;
|
||||||
let handled = true;
|
let handled = true;
|
||||||
|
|
||||||
|
// HOME and END are handled by RovingTabIndexProvider
|
||||||
switch (ev.key) {
|
switch (ev.key) {
|
||||||
case Key.ARROW_UP:
|
case Key.ARROW_UP:
|
||||||
case Key.ARROW_DOWN:
|
case Key.ARROW_DOWN:
|
||||||
|
@ -47,8 +48,6 @@ const Toolbar: React.FC<IProps> = ({children, ...props}) => {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// HOME and END are handled by RovingTabIndexProvider
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
handled = false;
|
handled = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ import React from "react";
|
||||||
|
|
||||||
import AccessibleTooltipButton from "../../components/views/elements/AccessibleTooltipButton";
|
import AccessibleTooltipButton from "../../components/views/elements/AccessibleTooltipButton";
|
||||||
|
|
||||||
interface IProps extends React.ComponentProps<typeof AccessibleTooltipButton> {
|
interface IProps extends React.ComponentProps<typeof AccessibleTooltipButton> {
|
||||||
// whether or not the context menu is currently open
|
// whether or not the context menu is currently open
|
||||||
isExpanded: boolean;
|
isExpanded: boolean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,8 @@ import AccessibleTooltipButton from "../../components/views/elements/AccessibleT
|
||||||
import {useRovingTabIndex} from "../RovingTabIndex";
|
import {useRovingTabIndex} from "../RovingTabIndex";
|
||||||
import {Ref} from "./types";
|
import {Ref} from "./types";
|
||||||
|
|
||||||
interface IProps extends Omit<React.ComponentProps<typeof AccessibleTooltipButton>, "onFocus" | "inputRef" | "tabIndex"> {
|
type ATBProps = React.ComponentProps<typeof AccessibleTooltipButton>;
|
||||||
|
interface IProps extends Omit<ATBProps, "onFocus" | "inputRef" | "tabIndex"> {
|
||||||
inputRef?: Ref;
|
inputRef?: Ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@ limitations under the License.
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import AccessibleButton from "../../components/views/elements/AccessibleButton";
|
|
||||||
import {useRovingTabIndex} from "../RovingTabIndex";
|
import {useRovingTabIndex} from "../RovingTabIndex";
|
||||||
import {FocusHandler, Ref} from "./types";
|
import {FocusHandler, Ref} from "./types";
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,11 @@ export default class CommandProvider extends AutocompleteProvider {
|
||||||
|
|
||||||
renderCompletions(completions: React.ReactNode[]): React.ReactNode {
|
renderCompletions(completions: React.ReactNode[]): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<div className="mx_Autocomplete_Completion_container_block" role="listbox" aria-label={_t("Command Autocomplete")}>
|
<div
|
||||||
|
className="mx_Autocomplete_Completion_container_block"
|
||||||
|
role="listbox"
|
||||||
|
aria-label={_t("Command Autocomplete")}
|
||||||
|
>
|
||||||
{ completions }
|
{ completions }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -91,15 +91,15 @@ export default class CommunityProvider extends AutocompleteProvider {
|
||||||
href: makeGroupPermalink(groupId),
|
href: makeGroupPermalink(groupId),
|
||||||
component: (
|
component: (
|
||||||
<PillCompletion title={name} description={groupId}>
|
<PillCompletion title={name} description={groupId}>
|
||||||
<BaseAvatar name={name || groupId}
|
<BaseAvatar
|
||||||
width={24}
|
name={name || groupId}
|
||||||
height={24}
|
width={24}
|
||||||
url={avatarUrl ? cli.mxcUrlToHttp(avatarUrl, 24, 24) : null} />
|
height={24}
|
||||||
|
url={avatarUrl ? cli.mxcUrlToHttp(avatarUrl, 24, 24) : null} />
|
||||||
</PillCompletion>
|
</PillCompletion>
|
||||||
),
|
),
|
||||||
range,
|
range,
|
||||||
}))
|
})).slice(0, 4);
|
||||||
.slice(0, 4);
|
|
||||||
}
|
}
|
||||||
return completions;
|
return completions;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,9 +34,9 @@ export const TextualCompletion = forwardRef<ITextualCompletionProps, any>((props
|
||||||
const {title, subtitle, description, className, ...restProps} = props;
|
const {title, subtitle, description, className, ...restProps} = props;
|
||||||
return (
|
return (
|
||||||
<div {...restProps}
|
<div {...restProps}
|
||||||
className={classNames('mx_Autocomplete_Completion_block', className)}
|
className={classNames('mx_Autocomplete_Completion_block', className)}
|
||||||
role="option"
|
role="option"
|
||||||
ref={ref}
|
ref={ref}
|
||||||
>
|
>
|
||||||
<span className="mx_Autocomplete_Completion_title">{ title }</span>
|
<span className="mx_Autocomplete_Completion_title">{ title }</span>
|
||||||
<span className="mx_Autocomplete_Completion_subtitle">{ subtitle }</span>
|
<span className="mx_Autocomplete_Completion_subtitle">{ subtitle }</span>
|
||||||
|
@ -53,9 +53,9 @@ export const PillCompletion = forwardRef<IPillCompletionProps, any>((props, ref)
|
||||||
const {title, subtitle, description, className, children, ...restProps} = props;
|
const {title, subtitle, description, className, children, ...restProps} = props;
|
||||||
return (
|
return (
|
||||||
<div {...restProps}
|
<div {...restProps}
|
||||||
className={classNames('mx_Autocomplete_Completion_pill', className)}
|
className={classNames('mx_Autocomplete_Completion_pill', className)}
|
||||||
role="option"
|
role="option"
|
||||||
ref={ref}
|
ref={ref}
|
||||||
>
|
>
|
||||||
{ children }
|
{ children }
|
||||||
<span className="mx_Autocomplete_Completion_title">{ title }</span>
|
<span className="mx_Autocomplete_Completion_title">{ title }</span>
|
||||||
|
|
|
@ -139,7 +139,11 @@ export default class EmojiProvider extends AutocompleteProvider {
|
||||||
|
|
||||||
renderCompletions(completions: React.ReactNode[]): React.ReactNode {
|
renderCompletions(completions: React.ReactNode[]): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<div className="mx_Autocomplete_Completion_container_pill" role="listbox" aria-label={_t("Emoji Autocomplete")}>
|
<div
|
||||||
|
className="mx_Autocomplete_Completion_container_pill"
|
||||||
|
role="listbox"
|
||||||
|
aria-label={_t("Emoji Autocomplete")}
|
||||||
|
>
|
||||||
{ completions }
|
{ completions }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -110,9 +110,7 @@ export default class RoomProvider extends AutocompleteProvider {
|
||||||
),
|
),
|
||||||
range,
|
range,
|
||||||
};
|
};
|
||||||
})
|
}).filter((completion) => !!completion.completion && completion.completion.length > 0).slice(0, 4);
|
||||||
.filter((completion) => !!completion.completion && completion.completion.length > 0)
|
|
||||||
.slice(0, 4);
|
|
||||||
}
|
}
|
||||||
return completions;
|
return completions;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,8 +71,13 @@ export default class UserProvider extends AutocompleteProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private onRoomTimeline = (ev: MatrixEvent, room: Room, toStartOfTimeline: boolean, removed: boolean,
|
private onRoomTimeline = (
|
||||||
data: IRoomTimelineData) => {
|
ev: MatrixEvent,
|
||||||
|
room: Room,
|
||||||
|
toStartOfTimeline: boolean,
|
||||||
|
removed: boolean,
|
||||||
|
data: IRoomTimelineData,
|
||||||
|
) => {
|
||||||
if (!room) return;
|
if (!room) return;
|
||||||
if (removed) return;
|
if (removed) return;
|
||||||
if (room.roomId !== this.room.roomId) return;
|
if (room.roomId !== this.room.roomId) return;
|
||||||
|
@ -171,7 +176,11 @@ export default class UserProvider extends AutocompleteProvider {
|
||||||
|
|
||||||
renderCompletions(completions: React.ReactNode[]): React.ReactNode {
|
renderCompletions(completions: React.ReactNode[]): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<div className="mx_Autocomplete_Completion_container_pill" role="listbox" aria-label={_t("User Autocomplete")}>
|
<div
|
||||||
|
className="mx_Autocomplete_Completion_container_pill"
|
||||||
|
role="listbox"
|
||||||
|
aria-label={_t("User Autocomplete")}
|
||||||
|
>
|
||||||
{ completions }
|
{ completions }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -233,8 +233,7 @@ export class ContextMenu extends React.PureComponent<IProps, IState> {
|
||||||
switch (ev.key) {
|
switch (ev.key) {
|
||||||
case Key.TAB:
|
case Key.TAB:
|
||||||
case Key.ESCAPE:
|
case Key.ESCAPE:
|
||||||
// close on left and right arrows too for when it is a context menu on a <Toolbar />
|
case Key.ARROW_LEFT: // close on left and right arrows too for when it is a context menu on a <Toolbar />
|
||||||
case Key.ARROW_LEFT:
|
|
||||||
case Key.ARROW_RIGHT:
|
case Key.ARROW_RIGHT:
|
||||||
this.props.onFinished();
|
this.props.onFinished();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -377,7 +377,7 @@ export default class LeftPanel 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_LeftPanel_tagPanelContainer">
|
<div className="mx_LeftPanel_tagPanelContainer">
|
||||||
<TagPanel/>
|
<TagPanel />
|
||||||
{SettingsStore.getValue("feature_custom_tags") ? <CustomRoomTagPanel /> : null}
|
{SettingsStore.getValue("feature_custom_tags") ? <CustomRoomTagPanel /> : null}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -43,11 +43,11 @@ import PlatformPeg from "../../PlatformPeg";
|
||||||
import { DefaultTagID } from "../../stores/room-list/models";
|
import { DefaultTagID } from "../../stores/room-list/models";
|
||||||
import {
|
import {
|
||||||
showToast as showSetPasswordToast,
|
showToast as showSetPasswordToast,
|
||||||
hideToast as hideSetPasswordToast
|
hideToast as hideSetPasswordToast,
|
||||||
} from "../../toasts/SetPasswordToast";
|
} from "../../toasts/SetPasswordToast";
|
||||||
import {
|
import {
|
||||||
showToast as showServerLimitToast,
|
showToast as showServerLimitToast,
|
||||||
hideToast as hideServerLimitToast
|
hideToast as hideServerLimitToast,
|
||||||
} from "../../toasts/ServerLimitToast";
|
} from "../../toasts/ServerLimitToast";
|
||||||
import { Action } from "../../dispatcher/actions";
|
import { Action } from "../../dispatcher/actions";
|
||||||
import LeftPanel from "./LeftPanel";
|
import LeftPanel from "./LeftPanel";
|
||||||
|
@ -79,6 +79,7 @@ interface IProps {
|
||||||
initialEventPixelOffset: number;
|
initialEventPixelOffset: number;
|
||||||
leftDisabled: boolean;
|
leftDisabled: boolean;
|
||||||
rightDisabled: boolean;
|
rightDisabled: boolean;
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
page_type: string;
|
page_type: string;
|
||||||
autoJoin: boolean;
|
autoJoin: boolean;
|
||||||
thirdPartyInvite?: object;
|
thirdPartyInvite?: object;
|
||||||
|
@ -98,7 +99,9 @@ interface IProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IUsageLimit {
|
interface IUsageLimit {
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
limit_type: "monthly_active_user" | string;
|
limit_type: "monthly_active_user" | string;
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
admin_contact?: string;
|
admin_contact?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,10 +319,10 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
_calculateServerLimitToast(syncErrorData: IState["syncErrorData"], usageLimitEventContent?: IUsageLimit) {
|
_calculateServerLimitToast(syncError: IState["syncErrorData"], usageLimitEventContent?: IUsageLimit) {
|
||||||
const error = syncErrorData && syncErrorData.error && syncErrorData.error.errcode === "M_RESOURCE_LIMIT_EXCEEDED";
|
const error = syncError && syncError.error && syncError.error.errcode === "M_RESOURCE_LIMIT_EXCEEDED";
|
||||||
if (error) {
|
if (error) {
|
||||||
usageLimitEventContent = syncErrorData.error.data;
|
usageLimitEventContent = syncError.error.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (usageLimitEventContent) {
|
if (usageLimitEventContent) {
|
||||||
|
@ -620,18 +623,18 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||||
switch (this.props.page_type) {
|
switch (this.props.page_type) {
|
||||||
case PageTypes.RoomView:
|
case PageTypes.RoomView:
|
||||||
pageElement = <RoomView
|
pageElement = <RoomView
|
||||||
ref={this._roomView}
|
ref={this._roomView}
|
||||||
autoJoin={this.props.autoJoin}
|
autoJoin={this.props.autoJoin}
|
||||||
onRegistered={this.props.onRegistered}
|
onRegistered={this.props.onRegistered}
|
||||||
thirdPartyInvite={this.props.thirdPartyInvite}
|
thirdPartyInvite={this.props.thirdPartyInvite}
|
||||||
oobData={this.props.roomOobData}
|
oobData={this.props.roomOobData}
|
||||||
viaServers={this.props.viaServers}
|
viaServers={this.props.viaServers}
|
||||||
eventPixelOffset={this.props.initialEventPixelOffset}
|
eventPixelOffset={this.props.initialEventPixelOffset}
|
||||||
key={this.props.currentRoomId || 'roomview'}
|
key={this.props.currentRoomId || 'roomview'}
|
||||||
disabled={this.props.middleDisabled}
|
disabled={this.props.middleDisabled}
|
||||||
ConferenceHandler={this.props.ConferenceHandler}
|
ConferenceHandler={this.props.ConferenceHandler}
|
||||||
resizeNotifier={this.props.resizeNotifier}
|
resizeNotifier={this.props.resizeNotifier}
|
||||||
/>;
|
/>;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PageTypes.MyGroups:
|
case PageTypes.MyGroups:
|
||||||
|
|
|
@ -69,7 +69,7 @@ import { ViewUserPayload } from "../../dispatcher/payloads/ViewUserPayload";
|
||||||
import { Action } from "../../dispatcher/actions";
|
import { Action } from "../../dispatcher/actions";
|
||||||
import {
|
import {
|
||||||
showToast as showAnalyticsToast,
|
showToast as showAnalyticsToast,
|
||||||
hideToast as hideAnalyticsToast
|
hideToast as hideAnalyticsToast,
|
||||||
} from "../../toasts/AnalyticsToast";
|
} from "../../toasts/AnalyticsToast";
|
||||||
import {showToast as showNotificationsToast} from "../../toasts/DesktopNotificationsToast";
|
import {showToast as showNotificationsToast} from "../../toasts/DesktopNotificationsToast";
|
||||||
import { OpenToTabPayload } from "../../dispatcher/payloads/OpenToTabPayload";
|
import { OpenToTabPayload } from "../../dispatcher/payloads/OpenToTabPayload";
|
||||||
|
@ -129,6 +129,7 @@ interface IScreen {
|
||||||
params?: object;
|
params?: object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* eslint-disable camelcase */
|
||||||
interface IRoomInfo {
|
interface IRoomInfo {
|
||||||
room_id?: string;
|
room_id?: string;
|
||||||
room_alias?: string;
|
room_alias?: string;
|
||||||
|
@ -140,6 +141,7 @@ interface IRoomInfo {
|
||||||
oob_data?: object;
|
oob_data?: object;
|
||||||
via_servers?: string[];
|
via_servers?: string[];
|
||||||
}
|
}
|
||||||
|
/* eslint-enable camelcase */
|
||||||
|
|
||||||
interface IProps { // TODO type things better
|
interface IProps { // TODO type things better
|
||||||
config: Record<string, any>;
|
config: Record<string, any>;
|
||||||
|
@ -165,6 +167,7 @@ interface IState {
|
||||||
// the master view we are showing.
|
// the master view we are showing.
|
||||||
view: Views;
|
view: Views;
|
||||||
// What the LoggedInView would be showing if visible
|
// What the LoggedInView would be showing if visible
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
page_type?: PageTypes;
|
page_type?: PageTypes;
|
||||||
// The ID of the room we're viewing. This is either populated directly
|
// The ID of the room we're viewing. This is either populated directly
|
||||||
// in the case where we view a room by ID or by RoomView when it resolves
|
// in the case where we view a room by ID or by RoomView when it resolves
|
||||||
|
@ -180,8 +183,11 @@ interface IState {
|
||||||
middleDisabled: boolean;
|
middleDisabled: boolean;
|
||||||
// the right panel's disabled state is tracked in its store.
|
// the right panel's disabled state is tracked in its store.
|
||||||
// Parameters used in the registration dance with the IS
|
// Parameters used in the registration dance with the IS
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
register_client_secret?: string;
|
register_client_secret?: string;
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
register_session_id?: string;
|
register_session_id?: string;
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
register_id_sid?: string;
|
register_id_sid?: string;
|
||||||
// When showing Modal dialogs we need to set aria-hidden on the root app element
|
// When showing Modal dialogs we need to set aria-hidden on the root app element
|
||||||
// and disable it when there are no dialogs
|
// and disable it when there are no dialogs
|
||||||
|
@ -341,6 +347,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: [REACT-WARNING] Replace with appropriate lifecycle stage
|
// TODO: [REACT-WARNING] Replace with appropriate lifecycle stage
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
UNSAFE_componentWillUpdate(props, state) {
|
UNSAFE_componentWillUpdate(props, state) {
|
||||||
if (this.shouldTrackPageChange(this.state, state)) {
|
if (this.shouldTrackPageChange(this.state, state)) {
|
||||||
this.startPageChangeTimer();
|
this.startPageChangeTimer();
|
||||||
|
@ -610,8 +617,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||||
const UserSettingsDialog = sdk.getComponent("dialogs.UserSettingsDialog");
|
const UserSettingsDialog = sdk.getComponent("dialogs.UserSettingsDialog");
|
||||||
Modal.createTrackedDialog('User settings', '', UserSettingsDialog,
|
Modal.createTrackedDialog('User settings', '', UserSettingsDialog,
|
||||||
{initialTabId: tabPayload.initialTabId},
|
{initialTabId: tabPayload.initialTabId},
|
||||||
/*className=*/null, /*isPriority=*/false, /*isStatic=*/true
|
/*className=*/null, /*isPriority=*/false, /*isStatic=*/true);
|
||||||
);
|
|
||||||
|
|
||||||
// View the welcome or home page if we need something to look at
|
// View the welcome or home page if we need something to look at
|
||||||
this.viewSomethingBehindModal();
|
this.viewSomethingBehindModal();
|
||||||
|
@ -1080,7 +1086,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||||
title: _t("Leave room"),
|
title: _t("Leave room"),
|
||||||
description: (
|
description: (
|
||||||
<span>
|
<span>
|
||||||
{ _t("Are you sure you want to leave the room '%(roomName)s'?", {roomName: roomToLeave.name}) }
|
{ _t("Are you sure you want to leave the room '%(roomName)s'?", {roomName: roomToLeave.name}) }
|
||||||
{ warnings }
|
{ warnings }
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
|
@ -1433,7 +1439,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||||
cli.on("crypto.warning", (type) => {
|
cli.on("crypto.warning", (type) => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'CRYPTO_WARNING_OLD_VERSION_DETECTED':
|
case 'CRYPTO_WARNING_OLD_VERSION_DETECTED':
|
||||||
const brand = SdkConfig.get().brand;
|
|
||||||
Modal.createTrackedDialog('Crypto migrated', '', ErrorDialog, {
|
Modal.createTrackedDialog('Crypto migrated', '', ErrorDialog, {
|
||||||
title: _t('Old cryptography data detected'),
|
title: _t('Old cryptography data detected'),
|
||||||
description: _t(
|
description: _t(
|
||||||
|
@ -1444,7 +1449,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||||
"in this version. This may also cause messages exchanged with this " +
|
"in this version. This may also cause messages exchanged with this " +
|
||||||
"version to fail. If you experience problems, log out and back in " +
|
"version to fail. If you experience problems, log out and back in " +
|
||||||
"again. To retain message history, export and re-import your keys.",
|
"again. To retain message history, export and re-import your keys.",
|
||||||
{ brand },
|
{ brand: SdkConfig.get().brand },
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -20,7 +20,6 @@ import classNames from "classnames";
|
||||||
import defaultDispatcher from "../../dispatcher/dispatcher";
|
import defaultDispatcher from "../../dispatcher/dispatcher";
|
||||||
import { _t } from "../../languageHandler";
|
import { _t } from "../../languageHandler";
|
||||||
import { ActionPayload } from "../../dispatcher/payloads";
|
import { ActionPayload } from "../../dispatcher/payloads";
|
||||||
import { throttle } from 'lodash';
|
|
||||||
import { Key } from "../../Keyboard";
|
import { Key } from "../../Keyboard";
|
||||||
import AccessibleButton from "../views/elements/AccessibleButton";
|
import AccessibleButton from "../views/elements/AccessibleButton";
|
||||||
import { Action } from "../../dispatcher/actions";
|
import { Action } from "../../dispatcher/actions";
|
||||||
|
@ -137,7 +136,7 @@ export default class RoomSearch extends React.PureComponent<IProps, IState> {
|
||||||
});
|
});
|
||||||
|
|
||||||
let icon = (
|
let icon = (
|
||||||
<div className='mx_RoomSearch_icon'/>
|
<div className='mx_RoomSearch_icon' />
|
||||||
);
|
);
|
||||||
let input = (
|
let input = (
|
||||||
<input
|
<input
|
||||||
|
|
|
@ -18,7 +18,6 @@ limitations under the License.
|
||||||
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import {_t} from '../../languageHandler';
|
import {_t} from '../../languageHandler';
|
||||||
import * as PropTypes from "prop-types";
|
|
||||||
import * as sdk from "../../index";
|
import * as sdk from "../../index";
|
||||||
import AutoHideScrollbar from './AutoHideScrollbar';
|
import AutoHideScrollbar from './AutoHideScrollbar';
|
||||||
import { ReactNode } from "react";
|
import { ReactNode } from "react";
|
||||||
|
|
|
@ -40,7 +40,7 @@ import AccessibleTooltipButton from "../views/elements/AccessibleTooltipButton";
|
||||||
import { SettingLevel } from "../../settings/SettingLevel";
|
import { SettingLevel } from "../../settings/SettingLevel";
|
||||||
import IconizedContextMenu, {
|
import IconizedContextMenu, {
|
||||||
IconizedContextMenuOption,
|
IconizedContextMenuOption,
|
||||||
IconizedContextMenuOptionList
|
IconizedContextMenuOptionList,
|
||||||
} from "../views/context_menus/IconizedContextMenu";
|
} from "../views/context_menus/IconizedContextMenu";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
|
@ -234,12 +234,12 @@ export default class UserMenu extends React.Component<IProps, IState> {
|
||||||
>
|
>
|
||||||
<div className="mx_UserMenu_contextMenu_header">
|
<div className="mx_UserMenu_contextMenu_header">
|
||||||
<div className="mx_UserMenu_contextMenu_name">
|
<div className="mx_UserMenu_contextMenu_name">
|
||||||
<span className="mx_UserMenu_contextMenu_displayName">
|
<span className="mx_UserMenu_contextMenu_displayName">
|
||||||
{OwnProfileStore.instance.displayName}
|
{OwnProfileStore.instance.displayName}
|
||||||
</span>
|
</span>
|
||||||
<span className="mx_UserMenu_contextMenu_userId">
|
<span className="mx_UserMenu_contextMenu_userId">
|
||||||
{MatrixClientPeg.get().getUserId()}
|
{MatrixClientPeg.get().getUserId()}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<AccessibleTooltipButton
|
<AccessibleTooltipButton
|
||||||
className="mx_UserMenu_contextMenu_themeButton"
|
className="mx_UserMenu_contextMenu_themeButton"
|
||||||
|
|
|
@ -17,7 +17,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, {useCallback, useContext, useEffect, useMemo, useState} from 'react';
|
import React, {useCallback, useContext, useEffect, useState} from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import * as AvatarLogic from '../../../Avatar';
|
import * as AvatarLogic from '../../../Avatar';
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
import SettingsStore from "../../../settings/SettingsStore";
|
||||||
|
@ -96,7 +96,7 @@ const BaseAvatar = (props: IProps) => {
|
||||||
urls,
|
urls,
|
||||||
width = 40,
|
width = 40,
|
||||||
height = 40,
|
height = 40,
|
||||||
resizeMethod = "crop", // eslint-disable-line no-unused-vars
|
resizeMethod = "crop", // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
defaultToInitialLetter = true,
|
defaultToInitialLetter = true,
|
||||||
onClick,
|
onClick,
|
||||||
inputRef,
|
inputRef,
|
||||||
|
|
|
@ -126,7 +126,7 @@ export default class DecoratedRoomAvatar extends React.PureComponent<IProps, ISt
|
||||||
private onPresenceUpdate = () => {
|
private onPresenceUpdate = () => {
|
||||||
if (this.isUnmounted) return;
|
if (this.isUnmounted) return;
|
||||||
|
|
||||||
let newIcon = this.getPresenceIcon();
|
const newIcon = this.getPresenceIcon();
|
||||||
if (newIcon !== this.state.icon) this.setState({icon: newIcon});
|
if (newIcon !== this.state.icon) this.setState({icon: newIcon});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ export default class GroupAvatar extends React.Component<IProps> {
|
||||||
render() {
|
render() {
|
||||||
// extract the props we use from props so we can pass any others through
|
// extract the props we use from props so we can pass any others through
|
||||||
// should consider adding this as a global rule in js-sdk?
|
// should consider adding this as a global rule in js-sdk?
|
||||||
/*eslint no-unused-vars: ["error", { "ignoreRestSiblings": true }]*/
|
/* eslint @typescript-eslint/no-unused-vars: ["error", { "ignoreRestSiblings": true }] */
|
||||||
const {groupId, groupAvatarUrl, groupName, ...otherProps} = this.props;
|
const {groupId, groupAvatarUrl, groupName, ...otherProps} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -21,9 +21,6 @@ import { IDialogProps } from "./IDialogProps";
|
||||||
import Field from "../elements/Field";
|
import Field from "../elements/Field";
|
||||||
import AccessibleButton from "../elements/AccessibleButton";
|
import AccessibleButton from "../elements/AccessibleButton";
|
||||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||||
import InfoTooltip from "../elements/InfoTooltip";
|
|
||||||
import dis from "../../../dispatcher/dispatcher";
|
|
||||||
import {showCommunityRoomInviteDialog} from "../../../RoomInvite";
|
|
||||||
import { arrayFastClone } from "../../../utils/arrays";
|
import { arrayFastClone } from "../../../utils/arrays";
|
||||||
import SdkConfig from "../../../SdkConfig";
|
import SdkConfig from "../../../SdkConfig";
|
||||||
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
||||||
|
@ -31,7 +28,6 @@ import InviteDialog from "./InviteDialog";
|
||||||
import BaseAvatar from "../avatars/BaseAvatar";
|
import BaseAvatar from "../avatars/BaseAvatar";
|
||||||
import {getHttpUriForMxc} from "matrix-js-sdk/src/content-repo";
|
import {getHttpUriForMxc} from "matrix-js-sdk/src/content-repo";
|
||||||
import {inviteMultipleToRoom, showAnyInviteErrors} from "../../../RoomInvite";
|
import {inviteMultipleToRoom, showAnyInviteErrors} from "../../../RoomInvite";
|
||||||
import {humanizeTime} from "../../../utils/humanize";
|
|
||||||
import StyledCheckbox from "../elements/StyledCheckbox";
|
import StyledCheckbox from "../elements/StyledCheckbox";
|
||||||
import Modal from "../../../Modal";
|
import Modal from "../../../Modal";
|
||||||
import ErrorDialog from "./ErrorDialog";
|
import ErrorDialog from "./ErrorDialog";
|
||||||
|
@ -171,7 +167,7 @@ export default class CommunityPrototypeInviteDialog extends React.PureComponent<
|
||||||
public render() {
|
public render() {
|
||||||
const emailAddresses = [];
|
const emailAddresses = [];
|
||||||
this.state.emailTargets.forEach((address, i) => {
|
this.state.emailTargets.forEach((address, i) => {
|
||||||
emailAddresses.push(
|
emailAddresses.push((
|
||||||
<Field
|
<Field
|
||||||
key={i}
|
key={i}
|
||||||
value={address}
|
value={address}
|
||||||
|
@ -180,11 +176,11 @@ export default class CommunityPrototypeInviteDialog extends React.PureComponent<
|
||||||
placeholder={_t("Email address")}
|
placeholder={_t("Email address")}
|
||||||
onBlur={() => this.onAddressBlur(i)}
|
onBlur={() => this.onAddressBlur(i)}
|
||||||
/>
|
/>
|
||||||
);
|
));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Push a clean input
|
// Push a clean input
|
||||||
emailAddresses.push(
|
emailAddresses.push((
|
||||||
<Field
|
<Field
|
||||||
key={emailAddresses.length}
|
key={emailAddresses.length}
|
||||||
value={""}
|
value={""}
|
||||||
|
@ -192,23 +188,23 @@ export default class CommunityPrototypeInviteDialog extends React.PureComponent<
|
||||||
label={emailAddresses.length > 0 ? _t("Add another email") : _t("Email address")}
|
label={emailAddresses.length > 0 ? _t("Add another email") : _t("Email address")}
|
||||||
placeholder={emailAddresses.length > 0 ? _t("Add another email") : _t("Email address")}
|
placeholder={emailAddresses.length > 0 ? _t("Add another email") : _t("Email address")}
|
||||||
/>
|
/>
|
||||||
);
|
));
|
||||||
|
|
||||||
let peopleIntro = null;
|
let peopleIntro = null;
|
||||||
let people = [];
|
const people = [];
|
||||||
if (this.state.showPeople) {
|
if (this.state.showPeople) {
|
||||||
const humansToPresent = this.state.people.slice(0, this.state.numPeople);
|
const humansToPresent = this.state.people.slice(0, this.state.numPeople);
|
||||||
humansToPresent.forEach((person, i) => {
|
humansToPresent.forEach((person, i) => {
|
||||||
people.push(this.renderPerson(person, i));
|
people.push(this.renderPerson(person, i));
|
||||||
});
|
});
|
||||||
if (humansToPresent.length < this.state.people.length) {
|
if (humansToPresent.length < this.state.people.length) {
|
||||||
people.push(
|
people.push((
|
||||||
<AccessibleButton
|
<AccessibleButton
|
||||||
onClick={this.onShowMorePeople}
|
onClick={this.onShowMorePeople}
|
||||||
kind="link" key="more"
|
kind="link" key="more"
|
||||||
className="mx_CommunityPrototypeInviteDialog_morePeople"
|
className="mx_CommunityPrototypeInviteDialog_morePeople"
|
||||||
>{_t("Show more")}</AccessibleButton>
|
>{_t("Show more")}</AccessibleButton>
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.state.people.length > 0) {
|
if (this.state.people.length > 0) {
|
||||||
|
|
|
@ -163,8 +163,9 @@ export default class CreateCommunityPrototypeDialog extends React.PureComponent<
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
if (this.state.error) {
|
if (this.state.error) {
|
||||||
|
const classes = "mx_CreateCommunityPrototypeDialog_subtext mx_CreateCommunityPrototypeDialog_subtext_error";
|
||||||
helpText = (
|
helpText = (
|
||||||
<span className="mx_CreateCommunityPrototypeDialog_subtext mx_CreateCommunityPrototypeDialog_subtext_error">
|
<span className={classes}>
|
||||||
{this.state.error}
|
{this.state.error}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
@ -205,7 +206,10 @@ export default class CreateCommunityPrototypeDialog extends React.PureComponent<
|
||||||
ref={this.avatarUploadRef} accept="image/*"
|
ref={this.avatarUploadRef} accept="image/*"
|
||||||
onChange={this.onAvatarChanged}
|
onChange={this.onAvatarChanged}
|
||||||
/>
|
/>
|
||||||
<AccessibleButton onClick={this.onChangeAvatar} className="mx_CreateCommunityPrototypeDialog_avatarContainer">
|
<AccessibleButton
|
||||||
|
onClick={this.onChangeAvatar}
|
||||||
|
className="mx_CreateCommunityPrototypeDialog_avatarContainer"
|
||||||
|
>
|
||||||
{preview}
|
{preview}
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
<div className="mx_CreateCommunityPrototypeDialog_tip">
|
<div className="mx_CreateCommunityPrototypeDialog_tip">
|
||||||
|
|
|
@ -186,8 +186,8 @@ export default class ShareDialog extends React.PureComponent<IProps, IState> {
|
||||||
title = _t('Share Room Message');
|
title = _t('Share Room Message');
|
||||||
checkbox = <div>
|
checkbox = <div>
|
||||||
<StyledCheckbox
|
<StyledCheckbox
|
||||||
checked={this.state.linkSpecificEvent}
|
checked={this.state.linkSpecificEvent}
|
||||||
onClick={this.onLinkSpecificEventCheckboxClick}
|
onClick={this.onLinkSpecificEventCheckboxClick}
|
||||||
>
|
>
|
||||||
{ _t('Link to selected message') }
|
{ _t('Link to selected message') }
|
||||||
</StyledCheckbox>
|
</StyledCheckbox>
|
||||||
|
@ -198,16 +198,18 @@ export default class ShareDialog extends React.PureComponent<IProps, IState> {
|
||||||
const encodedUrl = encodeURIComponent(matrixToUrl);
|
const encodedUrl = encodeURIComponent(matrixToUrl);
|
||||||
|
|
||||||
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
|
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
|
||||||
return <BaseDialog title={title}
|
return <BaseDialog
|
||||||
className='mx_ShareDialog'
|
title={title}
|
||||||
contentId='mx_Dialog_content'
|
className='mx_ShareDialog'
|
||||||
onFinished={this.props.onFinished}
|
contentId='mx_Dialog_content'
|
||||||
|
onFinished={this.props.onFinished}
|
||||||
>
|
>
|
||||||
<div className="mx_ShareDialog_content">
|
<div className="mx_ShareDialog_content">
|
||||||
<div className="mx_ShareDialog_matrixto">
|
<div className="mx_ShareDialog_matrixto">
|
||||||
<a href={matrixToUrl}
|
<a
|
||||||
onClick={ShareDialog.onLinkClick}
|
href={matrixToUrl}
|
||||||
className="mx_ShareDialog_matrixto_link"
|
onClick={ShareDialog.onLinkClick}
|
||||||
|
className="mx_ShareDialog_matrixto_link"
|
||||||
>
|
>
|
||||||
{ matrixToUrl }
|
{ matrixToUrl }
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -34,7 +34,6 @@ export interface ILocationState {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class Draggable extends React.Component<IProps, IState> {
|
export default class Draggable extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
constructor(props: IProps) {
|
constructor(props: IProps) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
|
@ -77,5 +76,4 @@ export default class Draggable extends React.Component<IProps, IState> {
|
||||||
render() {
|
render() {
|
||||||
return <div className={this.props.className} onMouseDown={this.onMouseDown.bind(this)} />;
|
return <div className={this.props.className} onMouseDown={this.onMouseDown.bind(this)} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -39,11 +39,13 @@ interface IProps {
|
||||||
className: string;
|
className: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* eslint-disable camelcase */
|
||||||
interface IState {
|
interface IState {
|
||||||
userId: string;
|
userId: string;
|
||||||
displayname: string;
|
displayname: string;
|
||||||
avatar_url: string;
|
avatar_url: string;
|
||||||
}
|
}
|
||||||
|
/* eslint-enable camelcase */
|
||||||
|
|
||||||
const AVATAR_SIZE = 32;
|
const AVATAR_SIZE = 32;
|
||||||
|
|
||||||
|
@ -63,19 +65,18 @@ export default class EventTilePreview extends React.Component<IProps, IState> {
|
||||||
const client = MatrixClientPeg.get();
|
const client = MatrixClientPeg.get();
|
||||||
const userId = client.getUserId();
|
const userId = client.getUserId();
|
||||||
const profileInfo = await client.getProfileInfo(userId);
|
const profileInfo = await client.getProfileInfo(userId);
|
||||||
const avatar_url = Avatar.avatarUrlForUser(
|
const avatarUrl = Avatar.avatarUrlForUser(
|
||||||
{avatarUrl: profileInfo.avatar_url},
|
{avatarUrl: profileInfo.avatar_url},
|
||||||
AVATAR_SIZE, AVATAR_SIZE, "crop");
|
AVATAR_SIZE, AVATAR_SIZE, "crop");
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
userId,
|
userId,
|
||||||
displayname: profileInfo.displayname,
|
displayname: profileInfo.displayname,
|
||||||
avatar_url,
|
avatar_url: avatarUrl,
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fakeEvent({userId, displayname, avatar_url}: IState) {
|
private fakeEvent({userId, displayname, avatar_url: avatarUrl}: IState) {
|
||||||
// Fake it till we make it
|
// Fake it till we make it
|
||||||
const event = new MatrixEvent(JSON.parse(`{
|
const event = new MatrixEvent(JSON.parse(`{
|
||||||
"type": "m.room.message",
|
"type": "m.room.message",
|
||||||
|
@ -85,12 +86,12 @@ export default class EventTilePreview extends React.Component<IProps, IState> {
|
||||||
"msgtype": "m.text",
|
"msgtype": "m.text",
|
||||||
"body": "${this.props.message}",
|
"body": "${this.props.message}",
|
||||||
"displayname": "${displayname}",
|
"displayname": "${displayname}",
|
||||||
"avatar_url": "${avatar_url}"
|
"avatar_url": "${avatarUrl}"
|
||||||
},
|
},
|
||||||
"msgtype": "m.text",
|
"msgtype": "m.text",
|
||||||
"body": "${this.props.message}",
|
"body": "${this.props.message}",
|
||||||
"displayname": "${displayname}",
|
"displayname": "${displayname}",
|
||||||
"avatar_url": "${avatar_url}"
|
"avatar_url": "${avatarUrl}"
|
||||||
},
|
},
|
||||||
"unsigned": {
|
"unsigned": {
|
||||||
"age": 97
|
"age": 97
|
||||||
|
@ -104,7 +105,7 @@ export default class EventTilePreview extends React.Component<IProps, IState> {
|
||||||
name: displayname,
|
name: displayname,
|
||||||
userId: userId,
|
userId: userId,
|
||||||
getAvatarUrl: (..._) => {
|
getAvatarUrl: (..._) => {
|
||||||
return avatar_url;
|
return avatarUrl;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -114,13 +115,10 @@ export default class EventTilePreview extends React.Component<IProps, IState> {
|
||||||
public render() {
|
public render() {
|
||||||
const event = this.fakeEvent(this.state);
|
const event = this.fakeEvent(this.state);
|
||||||
|
|
||||||
let className = classnames(
|
const className = classnames(this.props.className, {
|
||||||
this.props.className,
|
"mx_IRCLayout": this.props.useIRCLayout,
|
||||||
{
|
"mx_GroupLayout": !this.props.useIRCLayout,
|
||||||
"mx_IRCLayout": this.props.useIRCLayout,
|
});
|
||||||
"mx_GroupLayout": !this.props.useIRCLayout,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return <div className={className}>
|
return <div className={className}>
|
||||||
<EventTile mxEvent={event} useIRCLayout={this.props.useIRCLayout} />
|
<EventTile mxEvent={event} useIRCLayout={this.props.useIRCLayout} />
|
||||||
|
|
|
@ -198,11 +198,9 @@ export default class Field extends React.PureComponent<PropShapes, IState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const {
|
/* eslint @typescript-eslint/no-unused-vars: ["error", { "ignoreRestSiblings": true }] */
|
||||||
element, prefixComponent, postfixComponent, className, onValidate, children,
|
const { element, prefixComponent, postfixComponent, className, onValidate, children,
|
||||||
tooltipContent, forceValidity, tooltipClassName, list, ...inputProps} = this.props;
|
tooltipContent, forceValidity, tooltipClassName, list, ...inputProps} = this.props;
|
||||||
|
|
||||||
// Set some defaults for the <input> element
|
// Set some defaults for the <input> element
|
||||||
|
|
|
@ -78,7 +78,12 @@ export default class IRCTimelineProfileResizer extends React.Component<IProps, I
|
||||||
|
|
||||||
private onMoueUp(event: MouseEvent) {
|
private onMoueUp(event: MouseEvent) {
|
||||||
if (this.props.roomId) {
|
if (this.props.roomId) {
|
||||||
SettingsStore.setValue("ircDisplayNameWidth", this.props.roomId, SettingLevel.ROOM_DEVICE, this.state.width);
|
SettingsStore.setValue(
|
||||||
|
"ircDisplayNameWidth",
|
||||||
|
this.props.roomId,
|
||||||
|
SettingLevel.ROOM_DEVICE,
|
||||||
|
this.state.width,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ limitations under the License.
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
import AccessibleButton from "./AccessibleButton";
|
|
||||||
import Tooltip from './Tooltip';
|
import Tooltip from './Tooltip';
|
||||||
import { _t } from "../../../languageHandler";
|
import { _t } from "../../../languageHandler";
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ const QRCode: React.FC<IProps> = ({data, className, ...options}) => {
|
||||||
return () => {
|
return () => {
|
||||||
cancelled = true;
|
cancelled = true;
|
||||||
};
|
};
|
||||||
}, [JSON.stringify(data), options]);
|
}, [JSON.stringify(data), options]); // eslint-disable-line react-hooks/exhaustive-deps
|
||||||
|
|
||||||
return <div className={classNames("mx_QRCode", className)}>
|
return <div className={classNames("mx_QRCode", className)}>
|
||||||
{ dataUri ? <img src={dataUri} className="mx_VerificationQRCode" alt={_t("QR Code")} /> : <Spinner /> }
|
{ dataUri ? <img src={dataUri} className="mx_VerificationQRCode" alt={_t("QR Code")} /> : <Spinner /> }
|
||||||
|
|
|
@ -45,7 +45,7 @@ export default class Slider extends React.Component<IProps> {
|
||||||
// non linear slider.
|
// non linear slider.
|
||||||
private offset(values: number[], value: number): number {
|
private offset(values: number[], value: number): number {
|
||||||
// the index of the first number greater than value.
|
// the index of the first number greater than value.
|
||||||
let closest = values.reduce((prev, curr) => {
|
const closest = values.reduce((prev, curr) => {
|
||||||
return (value > curr ? prev + 1 : prev);
|
return (value > curr ? prev + 1 : prev);
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
|
@ -68,17 +68,16 @@ export default class Slider extends React.Component<IProps> {
|
||||||
const linearInterpolation = (value - closestLessValue) / (closestGreaterValue - closestLessValue);
|
const linearInterpolation = (value - closestLessValue) / (closestGreaterValue - closestLessValue);
|
||||||
|
|
||||||
return 100 * (closest - 1 + linearInterpolation) * intervalWidth;
|
return 100 * (closest - 1 + linearInterpolation) * intervalWidth;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render(): React.ReactNode {
|
render(): React.ReactNode {
|
||||||
const dots = this.props.values.map(v =>
|
const dots = this.props.values.map(v => <Dot
|
||||||
<Dot active={v <= this.props.value}
|
active={v <= this.props.value}
|
||||||
label={this.props.displayFunc(v)}
|
label={this.props.displayFunc(v)}
|
||||||
onClick={this.props.disabled ? () => {} : () => this.props.onSelectionChange(v)}
|
onClick={this.props.disabled ? () => {} : () => this.props.onSelectionChange(v)}
|
||||||
key={v}
|
key={v}
|
||||||
disabled={this.props.disabled}
|
disabled={this.props.disabled}
|
||||||
/>);
|
/>);
|
||||||
|
|
||||||
let selection = null;
|
let selection = null;
|
||||||
|
|
||||||
|
@ -93,7 +92,7 @@ export default class Slider extends React.Component<IProps> {
|
||||||
return <div className="mx_Slider">
|
return <div className="mx_Slider">
|
||||||
<div>
|
<div>
|
||||||
<div className="mx_Slider_bar">
|
<div className="mx_Slider_bar">
|
||||||
<hr onClick={this.props.disabled ? () => {} : this.onClick.bind(this)}/>
|
<hr onClick={this.props.disabled ? () => {} : this.onClick.bind(this)} />
|
||||||
{ selection }
|
{ selection }
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_Slider_dotContainer">
|
<div className="mx_Slider_dotContainer">
|
||||||
|
|
|
@ -17,8 +17,6 @@ limitations under the License.
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { randomString } from "matrix-js-sdk/src/randomstring";
|
import { randomString } from "matrix-js-sdk/src/randomstring";
|
||||||
|
|
||||||
const CHECK_BOX_SVG = require("../../../../res/img/feather-customised/check.svg");
|
|
||||||
|
|
||||||
interface IProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
interface IProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,13 +37,14 @@ export default class StyledCheckbox extends React.PureComponent<IProps, IState>
|
||||||
}
|
}
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
|
/* eslint @typescript-eslint/no-unused-vars: ["error", { "ignoreRestSiblings": true }] */
|
||||||
const { children, className, ...otherProps } = this.props;
|
const { children, className, ...otherProps } = this.props;
|
||||||
return <span className={"mx_Checkbox " + className}>
|
return <span className={"mx_Checkbox " + className}>
|
||||||
<input id={this.id} {...otherProps} type="checkbox" />
|
<input id={this.id} {...otherProps} type="checkbox" />
|
||||||
<label htmlFor={this.id}>
|
<label htmlFor={this.id}>
|
||||||
{/* Using the div to center the image */}
|
{/* Using the div to center the image */}
|
||||||
<div className="mx_Checkbox_background">
|
<div className="mx_Checkbox_background">
|
||||||
<img src={CHECK_BOX_SVG}/>
|
<img src={require("../../../../res/img/feather-customised/check.svg")} />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{ this.props.children }
|
{ this.props.children }
|
||||||
|
|
|
@ -76,14 +76,16 @@ const EncryptionInfo: React.FC<IProps> = ({
|
||||||
description = (
|
description = (
|
||||||
<div>
|
<div>
|
||||||
<p>{_t("Messages in this room are end-to-end encrypted.")}</p>
|
<p>{_t("Messages in this room are end-to-end encrypted.")}</p>
|
||||||
<p>{_t("Your messages are secured and only you and the recipient have the unique keys to unlock them.")}</p>
|
<p>{_t("Your messages are secured and only you and the recipient have " +
|
||||||
|
"the unique keys to unlock them.")}</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
description = (
|
description = (
|
||||||
<div>
|
<div>
|
||||||
<p>{_t("Messages in this room are not end-to-end encrypted.")}</p>
|
<p>{_t("Messages in this room are not end-to-end encrypted.")}</p>
|
||||||
<p>{_t("In encrypted rooms, your messages are secured and only you and the recipient have the unique keys to unlock them.")}</p>
|
<p>{_t("In encrypted rooms, your messages are secured and only you and the recipient have " +
|
||||||
|
"the unique keys to unlock them.")}</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,10 @@ import dis from '../../../dispatcher/dispatcher';
|
||||||
import RightPanelStore from "../../../stores/RightPanelStore";
|
import RightPanelStore from "../../../stores/RightPanelStore";
|
||||||
import {RightPanelPhases} from "../../../stores/RightPanelStorePhases";
|
import {RightPanelPhases} from "../../../stores/RightPanelStorePhases";
|
||||||
import {Action} from '../../../dispatcher/actions';
|
import {Action} from '../../../dispatcher/actions';
|
||||||
import {SetRightPanelPhasePayload, SetRightPanelPhaseRefireParams} from '../../../dispatcher/payloads/SetRightPanelPhasePayload';
|
import {
|
||||||
|
SetRightPanelPhasePayload,
|
||||||
|
SetRightPanelPhaseRefireParams,
|
||||||
|
} from '../../../dispatcher/payloads/SetRightPanelPhasePayload';
|
||||||
import {EventSubscription} from "fbemitter";
|
import {EventSubscription} from "fbemitter";
|
||||||
|
|
||||||
export enum HeaderKind {
|
export enum HeaderKind {
|
||||||
|
@ -38,7 +41,7 @@ interface IState {
|
||||||
|
|
||||||
interface IProps {}
|
interface IProps {}
|
||||||
|
|
||||||
export default class HeaderButtons extends React.Component<IProps, IState> {
|
export default abstract class HeaderButtons extends React.Component<IProps, IState> {
|
||||||
private storeToken: EventSubscription;
|
private storeToken: EventSubscription;
|
||||||
private dispatcherRef: string;
|
private dispatcherRef: string;
|
||||||
|
|
||||||
|
@ -92,14 +95,7 @@ export default class HeaderButtons extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX: Make renderButtons a prop
|
// XXX: Make renderButtons a prop
|
||||||
public renderButtons(): JSX.Element[] {
|
public abstract renderButtons(): JSX.Element[];
|
||||||
// Ignore - intended to be overridden by subclasses
|
|
||||||
// Return empty fragment to satisfy the type
|
|
||||||
return [
|
|
||||||
<React.Fragment>
|
|
||||||
</React.Fragment>
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
// inline style as this will be swapped around in future commits
|
// inline style as this will be swapped around in future commits
|
||||||
|
|
|
@ -30,8 +30,6 @@ import {_t} from "../../../languageHandler";
|
||||||
import SdkConfig from "../../../SdkConfig";
|
import SdkConfig from "../../../SdkConfig";
|
||||||
import E2EIcon from "../rooms/E2EIcon";
|
import E2EIcon from "../rooms/E2EIcon";
|
||||||
import {
|
import {
|
||||||
PHASE_UNSENT,
|
|
||||||
PHASE_REQUESTED,
|
|
||||||
PHASE_READY,
|
PHASE_READY,
|
||||||
PHASE_DONE,
|
PHASE_DONE,
|
||||||
PHASE_STARTED,
|
PHASE_STARTED,
|
||||||
|
@ -104,14 +102,15 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
if (showSAS) {
|
if (showSAS) {
|
||||||
sasBlockDialog =
|
sasBlockDialog = <div className='mx_VerificationPanel_QRPhase_startOption'>
|
||||||
<div className='mx_VerificationPanel_QRPhase_startOption'>
|
<p>{_t("Compare unique emoji")}</p>
|
||||||
<p>{_t("Compare unique emoji")}</p>
|
<span className='mx_VerificationPanel_QRPhase_helpText'>
|
||||||
<span className='mx_VerificationPanel_QRPhase_helpText'>{_t("Compare a unique set of emoji if you don't have a camera on either device")}</span>
|
{_t("Compare a unique set of emoji if you don't have a camera on either device")}
|
||||||
<AccessibleButton disabled={this.state.emojiButtonClicked} onClick={this.startSAS} kind='primary'>
|
</span>
|
||||||
{_t("Start")}
|
<AccessibleButton disabled={this.state.emojiButtonClicked} onClick={this.startSAS} kind='primary'>
|
||||||
</AccessibleButton>
|
{_t("Start")}
|
||||||
</div>;
|
</AccessibleButton>
|
||||||
|
</div>;
|
||||||
}
|
}
|
||||||
const or = qrBlockDialog && sasBlockDialog ?
|
const or = qrBlockDialog && sasBlockDialog ?
|
||||||
<div className='mx_VerificationPanel_QRPhase_betweenText'>{_t("or")}</div> : null;
|
<div className='mx_VerificationPanel_QRPhase_betweenText'>{_t("or")}</div> : null;
|
||||||
|
@ -165,8 +164,8 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat
|
||||||
}
|
}
|
||||||
|
|
||||||
const noCommonMethodBlock = noCommonMethodError ?
|
const noCommonMethodBlock = noCommonMethodError ?
|
||||||
<div className="mx_UserInfo_container">{noCommonMethodError}</div> :
|
<div className="mx_UserInfo_container">{noCommonMethodError}</div> :
|
||||||
null;
|
null;
|
||||||
|
|
||||||
// TODO: add way to open camera to scan a QR code
|
// TODO: add way to open camera to scan a QR code
|
||||||
return <React.Fragment>
|
return <React.Fragment>
|
||||||
|
|
|
@ -92,6 +92,7 @@ export default class NotificationBadge extends React.PureComponent<XOR<IProps, I
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): React.ReactElement {
|
public render(): React.ReactElement {
|
||||||
|
/* eslint @typescript-eslint/no-unused-vars: ["error", { "ignoreRestSiblings": true }] */
|
||||||
const {notification, forceCount, roomId, onClick, ...props} = this.props;
|
const {notification, forceCount, roomId, onClick, ...props} = this.props;
|
||||||
|
|
||||||
// Don't show a badge if we don't need to
|
// Don't show a badge if we don't need to
|
||||||
|
|
|
@ -218,7 +218,7 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
|
||||||
|
|
||||||
private getRoomDelta = (roomId: string, delta: number, unread = false) => {
|
private getRoomDelta = (roomId: string, delta: number, unread = false) => {
|
||||||
const lists = RoomListStore.instance.orderedLists;
|
const lists = RoomListStore.instance.orderedLists;
|
||||||
let rooms: Room = [];
|
const rooms: Room = [];
|
||||||
TAG_ORDER.forEach(t => {
|
TAG_ORDER.forEach(t => {
|
||||||
let listRooms = lists[t];
|
let listRooms = lists[t];
|
||||||
|
|
||||||
|
@ -290,7 +290,7 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
|
||||||
// TODO: Put community invites in a more sensible place (not in the room list)
|
// TODO: Put community invites in a more sensible place (not in the room list)
|
||||||
// See https://github.com/vector-im/element-web/issues/14456
|
// See https://github.com/vector-im/element-web/issues/14456
|
||||||
return MatrixClientPeg.get().getGroups().filter(g => {
|
return MatrixClientPeg.get().getGroups().filter(g => {
|
||||||
return g.myMembership === 'invite';
|
return g.myMembership === 'invite';
|
||||||
}).map(g => {
|
}).map(g => {
|
||||||
const avatar = (
|
const avatar = (
|
||||||
<GroupAvatar
|
<GroupAvatar
|
||||||
|
@ -346,21 +346,19 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
|
||||||
: TAG_AESTHETICS[orderedTagId];
|
: TAG_AESTHETICS[orderedTagId];
|
||||||
if (!aesthetics) throw new Error(`Tag ${orderedTagId} does not have aesthetics`);
|
if (!aesthetics) throw new Error(`Tag ${orderedTagId} does not have aesthetics`);
|
||||||
|
|
||||||
components.push(
|
components.push(<RoomSublist
|
||||||
<RoomSublist
|
key={`sublist-${orderedTagId}`}
|
||||||
key={`sublist-${orderedTagId}`}
|
tagId={orderedTagId}
|
||||||
tagId={orderedTagId}
|
forRooms={true}
|
||||||
forRooms={true}
|
startAsHidden={aesthetics.defaultHidden}
|
||||||
startAsHidden={aesthetics.defaultHidden}
|
label={aesthetics.sectionLabelRaw ? aesthetics.sectionLabelRaw : _t(aesthetics.sectionLabel)}
|
||||||
label={aesthetics.sectionLabelRaw ? aesthetics.sectionLabelRaw : _t(aesthetics.sectionLabel)}
|
onAddRoom={aesthetics.onAddRoom}
|
||||||
onAddRoom={aesthetics.onAddRoom}
|
addRoomLabel={aesthetics.addRoomLabel ? _t(aesthetics.addRoomLabel) : aesthetics.addRoomLabel}
|
||||||
addRoomLabel={aesthetics.addRoomLabel ? _t(aesthetics.addRoomLabel) : aesthetics.addRoomLabel}
|
addRoomContextMenu={aesthetics.addRoomContextMenu}
|
||||||
addRoomContextMenu={aesthetics.addRoomContextMenu}
|
isMinimized={this.props.isMinimized}
|
||||||
isMinimized={this.props.isMinimized}
|
onResize={this.props.onResize}
|
||||||
onResize={this.props.onResize}
|
extraBadTilesThatShouldntExist={extraTiles}
|
||||||
extraBadTilesThatShouldntExist={extraTiles}
|
/>);
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return components;
|
return components;
|
||||||
|
|
|
@ -517,15 +517,13 @@ export default class RoomSublist extends React.Component<IProps, IState> {
|
||||||
if (this.state.rooms) {
|
if (this.state.rooms) {
|
||||||
const visibleRooms = this.state.rooms.slice(0, this.numVisibleTiles);
|
const visibleRooms = this.state.rooms.slice(0, this.numVisibleTiles);
|
||||||
for (const room of visibleRooms) {
|
for (const room of visibleRooms) {
|
||||||
tiles.push(
|
tiles.push(<RoomTile
|
||||||
<RoomTile
|
room={room}
|
||||||
room={room}
|
key={`room-${room.roomId}`}
|
||||||
key={`room-${room.roomId}`}
|
showMessagePreview={this.layout.showPreviews}
|
||||||
showMessagePreview={this.layout.showPreviews}
|
isMinimized={this.props.isMinimized}
|
||||||
isMinimized={this.props.isMinimized}
|
tag={this.props.tagId}
|
||||||
tag={this.props.tagId}
|
/>);
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -710,7 +708,12 @@ export default class RoomSublist extends React.Component<IProps, IState> {
|
||||||
// doesn't become sticky.
|
// doesn't become sticky.
|
||||||
// The same applies to the notification badge.
|
// The same applies to the notification badge.
|
||||||
return (
|
return (
|
||||||
<div className={classes} onKeyDown={this.onHeaderKeyDown} onFocus={onFocus} aria-label={this.props.label}>
|
<div
|
||||||
|
className={classes}
|
||||||
|
onKeyDown={this.onHeaderKeyDown}
|
||||||
|
onFocus={onFocus}
|
||||||
|
aria-label={this.props.label}
|
||||||
|
>
|
||||||
<div className="mx_RoomSublist_stickable">
|
<div className="mx_RoomSublist_stickable">
|
||||||
<Button
|
<Button
|
||||||
onFocus={onFocus}
|
onFocus={onFocus}
|
||||||
|
@ -762,7 +765,7 @@ export default class RoomSublist extends React.Component<IProps, IState> {
|
||||||
const showMoreAtMinHeight = minTiles < this.numTiles;
|
const showMoreAtMinHeight = minTiles < this.numTiles;
|
||||||
const minHeightPadding = RESIZE_HANDLE_HEIGHT + (showMoreAtMinHeight ? SHOW_N_BUTTON_HEIGHT : 0);
|
const minHeightPadding = RESIZE_HANDLE_HEIGHT + (showMoreAtMinHeight ? SHOW_N_BUTTON_HEIGHT : 0);
|
||||||
const minTilesPx = layout.tilesToPixelsWithPadding(minTiles, minHeightPadding);
|
const minTilesPx = layout.tilesToPixelsWithPadding(minTiles, minHeightPadding);
|
||||||
let maxTilesPx = layout.tilesToPixelsWithPadding(this.numTiles, this.padding);
|
const maxTilesPx = layout.tilesToPixelsWithPadding(this.numTiles, this.padding);
|
||||||
const showMoreBtnClasses = classNames({
|
const showMoreBtnClasses = classNames({
|
||||||
'mx_RoomSublist_showNButton': true,
|
'mx_RoomSublist_showNButton': true,
|
||||||
});
|
});
|
||||||
|
|
|
@ -31,7 +31,7 @@ import { ChevronFace, ContextMenuTooltipButton } from "../../structures/ContextM
|
||||||
import { DefaultTagID, TagID } from "../../../stores/room-list/models";
|
import { DefaultTagID, TagID } from "../../../stores/room-list/models";
|
||||||
import { MessagePreviewStore, ROOM_PREVIEW_CHANGED } from "../../../stores/room-list/MessagePreviewStore";
|
import { MessagePreviewStore, ROOM_PREVIEW_CHANGED } from "../../../stores/room-list/MessagePreviewStore";
|
||||||
import DecoratedRoomAvatar from "../avatars/DecoratedRoomAvatar";
|
import DecoratedRoomAvatar from "../avatars/DecoratedRoomAvatar";
|
||||||
import { ALL_MESSAGES, ALL_MESSAGES_LOUD, MENTIONS_ONLY, MUTE, } from "../../../RoomNotifs";
|
import { ALL_MESSAGES, ALL_MESSAGES_LOUD, MENTIONS_ONLY, MUTE } from "../../../RoomNotifs";
|
||||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||||
import NotificationBadge from "./NotificationBadge";
|
import NotificationBadge from "./NotificationBadge";
|
||||||
import { Volume } from "../../../RoomNotifsTypes";
|
import { Volume } from "../../../RoomNotifsTypes";
|
||||||
|
@ -48,7 +48,7 @@ import IconizedContextMenu, {
|
||||||
IconizedContextMenuCheckbox,
|
IconizedContextMenuCheckbox,
|
||||||
IconizedContextMenuOption,
|
IconizedContextMenuOption,
|
||||||
IconizedContextMenuOptionList,
|
IconizedContextMenuOptionList,
|
||||||
IconizedContextMenuRadio
|
IconizedContextMenuRadio,
|
||||||
} from "../context_menus/IconizedContextMenu";
|
} from "../context_menus/IconizedContextMenu";
|
||||||
import { CommunityPrototypeStore, IRoomProfile } from "../../../stores/CommunityPrototypeStore";
|
import { CommunityPrototypeStore, IRoomProfile } from "../../../stores/CommunityPrototypeStore";
|
||||||
import { UPDATE_EVENT } from "../../../stores/AsyncStore";
|
import { UPDATE_EVENT } from "../../../stores/AsyncStore";
|
||||||
|
@ -249,7 +249,7 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
|
||||||
removeTag,
|
removeTag,
|
||||||
addTag,
|
addTag,
|
||||||
undefined,
|
undefined,
|
||||||
0
|
0,
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
console.warn(`Unexpected tag ${tagId} applied to ${this.props.room.room_id}`);
|
console.warn(`Unexpected tag ${tagId} applied to ${this.props.room.room_id}`);
|
||||||
|
|
|
@ -19,9 +19,7 @@ import classNames from "classnames";
|
||||||
import {
|
import {
|
||||||
RovingAccessibleButton,
|
RovingAccessibleButton,
|
||||||
RovingAccessibleTooltipButton,
|
RovingAccessibleTooltipButton,
|
||||||
RovingTabIndexWrapper
|
|
||||||
} from "../../../accessibility/RovingTabIndex";
|
} from "../../../accessibility/RovingTabIndex";
|
||||||
import AccessibleButton from "../../views/elements/AccessibleButton";
|
|
||||||
import NotificationBadge from "./NotificationBadge";
|
import NotificationBadge from "./NotificationBadge";
|
||||||
import { NotificationState } from "../../../stores/notifications/NotificationState";
|
import { NotificationState } from "../../../stores/notifications/NotificationState";
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ function getStatusText(status: UpdateCheckStatus, errorDetail?: string) {
|
||||||
return _t('Downloading update...');
|
return _t('Downloading update...');
|
||||||
case UpdateCheckStatus.Ready:
|
case UpdateCheckStatus.Ready:
|
||||||
return _t("New version available. <a>Update now.</a>", {}, {
|
return _t("New version available. <a>Update now.</a>", {}, {
|
||||||
a: sub => <AccessibleButton kind="link" onClick={installUpdate}>{sub}</AccessibleButton>
|
a: sub => <AccessibleButton kind="link" onClick={installUpdate}>{sub}</AccessibleButton>,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,7 +170,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
|
||||||
"baseFontSize",
|
"baseFontSize",
|
||||||
null,
|
null,
|
||||||
SettingLevel.DEVICE,
|
SettingLevel.DEVICE,
|
||||||
parseInt(value, 10) - FontWatcher.SIZE_DIFF
|
parseInt(value, 10) - FontWatcher.SIZE_DIFF,
|
||||||
);
|
);
|
||||||
|
|
||||||
return {valid: true, feedback: _t('Use between %(min)s pt and %(max)s pt', {min, max})};
|
return {valid: true, feedback: _t('Use between %(min)s pt and %(max)s pt', {min, max})};
|
||||||
|
@ -294,7 +294,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{customThemeForm}
|
{customThemeForm}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,15 @@ interface IProps extends IGenericToastProps {
|
||||||
|
|
||||||
const SECOND = 1000;
|
const SECOND = 1000;
|
||||||
|
|
||||||
const GenericExpiringToast: React.FC<IProps> = ({description, acceptLabel, dismissLabel, onAccept, onDismiss, toastKey, numSeconds}) => {
|
const GenericExpiringToast: React.FC<IProps> = ({
|
||||||
|
description,
|
||||||
|
acceptLabel,
|
||||||
|
dismissLabel,
|
||||||
|
onAccept,
|
||||||
|
onDismiss,
|
||||||
|
toastKey,
|
||||||
|
numSeconds,
|
||||||
|
}) => {
|
||||||
const onReject = () => {
|
const onReject = () => {
|
||||||
if (onDismiss) onDismiss();
|
if (onDismiss) onDismiss();
|
||||||
ToastStore.sharedInstance().dismissToast(toastKey);
|
ToastStore.sharedInstance().dismissToast(toastKey);
|
||||||
|
|
|
@ -31,7 +31,13 @@ interface IPropsExtended extends IProps {
|
||||||
onReject();
|
onReject();
|
||||||
}
|
}
|
||||||
|
|
||||||
const GenericToast: React.FC<XOR<IPropsExtended, IProps>> = ({description, acceptLabel, rejectLabel, onAccept, onReject}) => {
|
const GenericToast: React.FC<XOR<IPropsExtended, IProps>> = ({
|
||||||
|
description,
|
||||||
|
acceptLabel,
|
||||||
|
rejectLabel,
|
||||||
|
onAccept,
|
||||||
|
onReject,
|
||||||
|
}) => {
|
||||||
return <div>
|
return <div>
|
||||||
<div className="mx_Toast_description">
|
<div className="mx_Toast_description">
|
||||||
{ description }
|
{ description }
|
||||||
|
|
|
@ -97,10 +97,7 @@ export default class CallView extends React.Component<IProps, IState> {
|
||||||
if (this.props.room) {
|
if (this.props.room) {
|
||||||
const roomId = this.props.room.roomId;
|
const roomId = this.props.room.roomId;
|
||||||
call = CallHandler.getCallForRoom(roomId) ||
|
call = CallHandler.getCallForRoom(roomId) ||
|
||||||
(this.props.ConferenceHandler ?
|
(this.props.ConferenceHandler ? this.props.ConferenceHandler.getConferenceCallForRoom(roomId) : null);
|
||||||
this.props.ConferenceHandler.getConferenceCallForRoom(roomId) :
|
|
||||||
null
|
|
||||||
);
|
|
||||||
|
|
||||||
if (this.call) {
|
if (this.call) {
|
||||||
this.setState({ call: call });
|
this.setState({ call: call });
|
||||||
|
|
|
@ -51,7 +51,7 @@ export default class IncomingCallBox extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
private onAction = (payload: ActionPayload) => {
|
private onAction = (payload: ActionPayload) => {
|
||||||
switch (payload.action) {
|
switch (payload.action) {
|
||||||
case 'call_state':
|
case 'call_state': {
|
||||||
const call = CallHandler.getCall(payload.room_id);
|
const call = CallHandler.getCall(payload.room_id);
|
||||||
if (call && call.call_state === 'ringing') {
|
if (call && call.call_state === 'ringing') {
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -62,6 +62,7 @@ export default class IncomingCallBox extends React.Component<IProps, IState> {
|
||||||
incomingCall: null,
|
incomingCall: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -442,7 +442,7 @@ export function pickBestLanguage(langs: string[]): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLangsJson(): Promise<object> {
|
function getLangsJson(): Promise<object> {
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let url;
|
let url;
|
||||||
if (typeof(webpackLangJsonUrl) === 'string') { // in Jest this 'url' isn't a URL, so just fall through
|
if (typeof(webpackLangJsonUrl) === 'string') { // in Jest this 'url' isn't a URL, so just fall through
|
||||||
url = webpackLangJsonUrl;
|
url = webpackLangJsonUrl;
|
||||||
|
@ -453,7 +453,7 @@ function getLangsJson(): Promise<object> {
|
||||||
{ method: "GET", url },
|
{ method: "GET", url },
|
||||||
(err, response, body) => {
|
(err, response, body) => {
|
||||||
if (err || response.status < 200 || response.status >= 300) {
|
if (err || response.status < 200 || response.status >= 300) {
|
||||||
reject({err: err, response: response});
|
reject(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
resolve(JSON.parse(body));
|
resolve(JSON.parse(body));
|
||||||
|
@ -488,7 +488,7 @@ function getLanguage(langPath: string): object {
|
||||||
{ method: "GET", url: langPath },
|
{ method: "GET", url: langPath },
|
||||||
(err, response, body) => {
|
(err, response, body) => {
|
||||||
if (err || response.status < 200 || response.status >= 300) {
|
if (err || response.status < 200 || response.status >= 300) {
|
||||||
reject({err: err, response: response});
|
reject(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
resolve(weblateToCounterpart(JSON.parse(body)));
|
resolve(weblateToCounterpart(JSON.parse(body)));
|
||||||
|
|
Loading…
Reference in a new issue