Improve types (#11239)
This commit is contained in:
parent
44615b2b04
commit
f1534fda79
12 changed files with 35 additions and 42 deletions
|
@ -256,7 +256,7 @@ export default class AddThreepid {
|
||||||
} else {
|
} else {
|
||||||
await this.matrixClient.addThreePid(
|
await this.matrixClient.addThreePid(
|
||||||
{
|
{
|
||||||
sid: this.sessionId,
|
sid: this.sessionId!,
|
||||||
client_secret: this.clientSecret,
|
client_secret: this.clientSecret,
|
||||||
id_server: getIdServerDomain(this.matrixClient),
|
id_server: getIdServerDomain(this.matrixClient),
|
||||||
},
|
},
|
||||||
|
@ -377,7 +377,7 @@ export default class AddThreepid {
|
||||||
} else {
|
} else {
|
||||||
await this.matrixClient.addThreePid(
|
await this.matrixClient.addThreePid(
|
||||||
{
|
{
|
||||||
sid: this.sessionId,
|
sid: this.sessionId!,
|
||||||
client_secret: this.clientSecret,
|
client_secret: this.clientSecret,
|
||||||
id_server: getIdServerDomain(this.matrixClient),
|
id_server: getIdServerDomain(this.matrixClient),
|
||||||
},
|
},
|
||||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import posthog, { PostHog, Properties } from "posthog-js";
|
import posthog, { CaptureOptions, PostHog, Properties } from "posthog-js";
|
||||||
import { MatrixClient } from "matrix-js-sdk/src/client";
|
import { MatrixClient } from "matrix-js-sdk/src/client";
|
||||||
import { logger } from "matrix-js-sdk/src/logger";
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
import { UserProperties } from "@matrix-org/analytics-events/types/typescript/UserProperties";
|
import { UserProperties } from "@matrix-org/analytics-events/types/typescript/UserProperties";
|
||||||
|
@ -56,10 +56,6 @@ export interface IPosthogEvent {
|
||||||
$set_once?: void;
|
$set_once?: void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IPostHogEventOptions {
|
|
||||||
timestamp?: Date;
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum Anonymity {
|
export enum Anonymity {
|
||||||
Disabled,
|
Disabled,
|
||||||
Anonymous,
|
Anonymous,
|
||||||
|
@ -256,19 +252,13 @@ export class PosthogAnalytics {
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-nextline no-unused-vars
|
// eslint-disable-nextline no-unused-vars
|
||||||
private capture(eventName: string, properties: Properties, options?: IPostHogEventOptions): void {
|
private capture(eventName: string, properties: Properties, options?: CaptureOptions): void {
|
||||||
if (!this.enabled) {
|
if (!this.enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { origin, hash, pathname } = window.location;
|
const { origin, hash, pathname } = window.location;
|
||||||
properties["redactedCurrentUrl"] = getRedactedCurrentLocation(origin, hash, pathname);
|
properties["redactedCurrentUrl"] = getRedactedCurrentLocation(origin, hash, pathname);
|
||||||
this.posthog.capture(
|
this.posthog.capture(eventName, { ...this.propertiesForNextEvent, ...properties }, options);
|
||||||
eventName,
|
|
||||||
{ ...this.propertiesForNextEvent, ...properties },
|
|
||||||
// TODO: Uncomment below once https://github.com/PostHog/posthog-js/pull/391
|
|
||||||
// gets merged
|
|
||||||
/* options as any, */ // No proper type definition in the posthog library
|
|
||||||
);
|
|
||||||
this.propertiesForNextEvent = {};
|
this.propertiesForNextEvent = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,7 +332,7 @@ export class PosthogAnalytics {
|
||||||
this.setAnonymity(Anonymity.Disabled);
|
this.setAnonymity(Anonymity.Disabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
public trackEvent<E extends IPosthogEvent>({ eventName, ...properties }: E, options?: IPostHogEventOptions): void {
|
public trackEvent<E extends IPosthogEvent>({ eventName, ...properties }: E, options?: CaptureOptions): void {
|
||||||
if (this.anonymity == Anonymity.Disabled || this.anonymity == Anonymity.Anonymous) return;
|
if (this.anonymity == Anonymity.Disabled || this.anonymity == Anonymity.Anonymous) return;
|
||||||
this.capture(eventName, properties, options);
|
this.capture(eventName, properties, options);
|
||||||
}
|
}
|
||||||
|
@ -420,7 +410,7 @@ export class PosthogAnalytics {
|
||||||
// that we want to accumulate before the user has given consent
|
// that we want to accumulate before the user has given consent
|
||||||
// All other scenarios should not track a user before they have given
|
// All other scenarios should not track a user before they have given
|
||||||
// explicit consent that they are ok with their analytics data being collected
|
// explicit consent that they are ok with their analytics data being collected
|
||||||
const options: IPostHogEventOptions = {};
|
const options: CaptureOptions = {};
|
||||||
const registrationTime = parseInt(window.localStorage.getItem("mx_registration_time")!, 10);
|
const registrationTime = parseInt(window.localStorage.getItem("mx_registration_time")!, 10);
|
||||||
if (!isNaN(registrationTime)) {
|
if (!isNaN(registrationTime)) {
|
||||||
options.timestamp = new Date(registrationTime);
|
options.timestamp = new Date(registrationTime);
|
||||||
|
|
|
@ -345,12 +345,15 @@ export default class ForgotPassword extends React.Component<Props, State> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private onInputChanged = (stateKey: string, ev: React.FormEvent<HTMLInputElement>): void => {
|
private onInputChanged = (
|
||||||
|
stateKey: "email" | "password" | "password2",
|
||||||
|
ev: React.FormEvent<HTMLInputElement>,
|
||||||
|
): void => {
|
||||||
let value = ev.currentTarget.value;
|
let value = ev.currentTarget.value;
|
||||||
if (stateKey === "email") value = value.trim();
|
if (stateKey === "email") value = value.trim();
|
||||||
this.setState({
|
this.setState({
|
||||||
[stateKey]: value,
|
[stateKey]: value,
|
||||||
} as any);
|
} as Pick<State, typeof stateKey>);
|
||||||
};
|
};
|
||||||
|
|
||||||
public renderEnterEmail(): JSX.Element {
|
public renderEnterEmail(): JSX.Element {
|
||||||
|
|
|
@ -29,7 +29,7 @@ interface EnterEmailProps {
|
||||||
errorText: string | ReactNode | null;
|
errorText: string | ReactNode | null;
|
||||||
homeserver: string;
|
homeserver: string;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
onInputChanged: (stateKey: string, ev: React.FormEvent<HTMLInputElement>) => void;
|
onInputChanged: (stateKey: "email", ev: React.FormEvent<HTMLInputElement>) => void;
|
||||||
onLoginClick: () => void;
|
onLoginClick: () => void;
|
||||||
onSubmitForm: (ev: React.FormEvent) => void;
|
onSubmitForm: (ev: React.FormEvent) => void;
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,7 +130,7 @@ export default class DeactivateAccountDialog extends React.Component<IProps, ISt
|
||||||
// but given that a deactivation is followed by a local logout and all object instances being thrown away
|
// but given that a deactivation is followed by a local logout and all object instances being thrown away
|
||||||
// this isn't done.
|
// this isn't done.
|
||||||
MatrixClientPeg.safeGet()
|
MatrixClientPeg.safeGet()
|
||||||
.deactivateAccount(auth, this.state.shouldErase)
|
.deactivateAccount(auth ?? undefined, this.state.shouldErase)
|
||||||
.then((r) => {
|
.then((r) => {
|
||||||
// Deactivation worked - logout & close this dialog
|
// Deactivation worked - logout & close this dialog
|
||||||
defaultDispatcher.fire(Action.TriggerLogout);
|
defaultDispatcher.fire(Action.TriggerLogout);
|
||||||
|
@ -163,7 +163,7 @@ export default class DeactivateAccountDialog extends React.Component<IProps, ISt
|
||||||
|
|
||||||
private initAuth(shouldErase: boolean): void {
|
private initAuth(shouldErase: boolean): void {
|
||||||
MatrixClientPeg.safeGet()
|
MatrixClientPeg.safeGet()
|
||||||
.deactivateAccount(null, shouldErase)
|
.deactivateAccount(undefined, shouldErase)
|
||||||
.then((r) => {
|
.then((r) => {
|
||||||
// If we got here, oops. The server didn't require any auth.
|
// If we got here, oops. The server didn't require any auth.
|
||||||
// Our application lifecycle will catch the error and do the logout bits.
|
// Our application lifecycle will catch the error and do the logout bits.
|
||||||
|
|
|
@ -37,7 +37,7 @@ export const StateEventEditor: React.FC<IEditorProps> = ({ mxEvent, onBack }) =>
|
||||||
[mxEvent],
|
[mxEvent],
|
||||||
);
|
);
|
||||||
|
|
||||||
const onSend = async ([eventType, stateKey]: string[], content?: IContent): Promise<void> => {
|
const onSend = async ([eventType, stateKey]: string[], content: IContent): Promise<void> => {
|
||||||
await cli.sendStateEvent(context.room.roomId, eventType, content, stateKey);
|
await cli.sendStateEvent(context.room.roomId, eventType, content, stateKey);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ interface IProps {
|
||||||
// XXX: It can take a cycle or two for the MessageActionBar to have all the props/setup
|
// XXX: It can take a cycle or two for the MessageActionBar to have all the props/setup
|
||||||
// required to get us a MediaEventHelper, so we use a getter function instead to prod for
|
// required to get us a MediaEventHelper, so we use a getter function instead to prod for
|
||||||
// one.
|
// one.
|
||||||
mediaEventHelperGet: () => MediaEventHelper;
|
mediaEventHelperGet: () => MediaEventHelper | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IState {
|
interface IState {
|
||||||
|
@ -53,9 +53,10 @@ export default class DownloadActionButton extends React.PureComponent<IProps, IS
|
||||||
}
|
}
|
||||||
|
|
||||||
private onDownloadClick = async (): Promise<void> => {
|
private onDownloadClick = async (): Promise<void> => {
|
||||||
if (this.state.loading) return;
|
const mediaEventHelper = this.props.mediaEventHelperGet();
|
||||||
|
if (this.state.loading || !mediaEventHelper) return;
|
||||||
|
|
||||||
if (this.props.mediaEventHelperGet().media.isEncrypted) {
|
if (mediaEventHelper.media.isEncrypted) {
|
||||||
this.setState({ tooltip: _td("Decrypting") });
|
this.setState({ tooltip: _td("Decrypting") });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +67,7 @@ export default class DownloadActionButton extends React.PureComponent<IProps, IS
|
||||||
return this.doDownload(this.state.blob);
|
return this.doDownload(this.state.blob);
|
||||||
}
|
}
|
||||||
|
|
||||||
const blob = await this.props.mediaEventHelperGet().sourceBlob.value;
|
const blob = await mediaEventHelper.sourceBlob.value;
|
||||||
this.setState({ blob });
|
this.setState({ blob });
|
||||||
await this.doDownload(blob);
|
await this.doDownload(blob);
|
||||||
};
|
};
|
||||||
|
@ -74,7 +75,7 @@ export default class DownloadActionButton extends React.PureComponent<IProps, IS
|
||||||
private async doDownload(blob: Blob): Promise<void> {
|
private async doDownload(blob: Blob): Promise<void> {
|
||||||
await this.downloader.download({
|
await this.downloader.download({
|
||||||
blob,
|
blob,
|
||||||
name: this.props.mediaEventHelperGet().fileName,
|
name: this.props.mediaEventHelperGet()!.fileName,
|
||||||
});
|
});
|
||||||
this.setState({ loading: false });
|
this.setState({ loading: false });
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,14 +53,13 @@ import { Key } from "../../../Keyboard";
|
||||||
import { ALTERNATE_KEY_NAME } from "../../../accessibility/KeyboardShortcuts";
|
import { ALTERNATE_KEY_NAME } from "../../../accessibility/KeyboardShortcuts";
|
||||||
import { Action } from "../../../dispatcher/actions";
|
import { Action } from "../../../dispatcher/actions";
|
||||||
import { ShowThreadPayload } from "../../../dispatcher/payloads/ShowThreadPayload";
|
import { ShowThreadPayload } from "../../../dispatcher/payloads/ShowThreadPayload";
|
||||||
import { GetRelationsForEvent } from "../rooms/EventTile";
|
import { GetRelationsForEvent, IEventTileType } from "../rooms/EventTile";
|
||||||
import { VoiceBroadcastInfoEventType } from "../../../voice-broadcast/types";
|
import { VoiceBroadcastInfoEventType } from "../../../voice-broadcast/types";
|
||||||
import { ButtonEvent } from "../elements/AccessibleButton";
|
import { ButtonEvent } from "../elements/AccessibleButton";
|
||||||
|
|
||||||
interface IOptionsButtonProps {
|
interface IOptionsButtonProps {
|
||||||
mxEvent: MatrixEvent;
|
mxEvent: MatrixEvent;
|
||||||
// TODO: Types
|
getTile: () => IEventTileType | null;
|
||||||
getTile: () => any | null;
|
|
||||||
getReplyChain: () => ReplyChain | null;
|
getReplyChain: () => ReplyChain | null;
|
||||||
permalinkCreator?: RoomPermalinkCreator;
|
permalinkCreator?: RoomPermalinkCreator;
|
||||||
onFocusChange: (menuDisplayed: boolean) => void;
|
onFocusChange: (menuDisplayed: boolean) => void;
|
||||||
|
@ -97,7 +96,7 @@ const OptionsButton: React.FC<IOptionsButtonProps> = ({
|
||||||
|
|
||||||
let contextMenu: ReactElement | undefined;
|
let contextMenu: ReactElement | undefined;
|
||||||
if (menuDisplayed && button.current) {
|
if (menuDisplayed && button.current) {
|
||||||
const tile = getTile && getTile();
|
const tile = getTile?.();
|
||||||
const replyChain = getReplyChain();
|
const replyChain = getReplyChain();
|
||||||
|
|
||||||
const buttonRect = button.current.getBoundingClientRect();
|
const buttonRect = button.current.getBoundingClientRect();
|
||||||
|
@ -254,8 +253,7 @@ const ReplyInThreadButton: React.FC<IReplyInThreadButton> = ({ mxEvent }) => {
|
||||||
interface IMessageActionBarProps {
|
interface IMessageActionBarProps {
|
||||||
mxEvent: MatrixEvent;
|
mxEvent: MatrixEvent;
|
||||||
reactions?: Relations | null | undefined;
|
reactions?: Relations | null | undefined;
|
||||||
// TODO: Types
|
getTile: () => IEventTileType | null;
|
||||||
getTile: () => any | null;
|
|
||||||
getReplyChain: () => ReplyChain | null;
|
getReplyChain: () => ReplyChain | null;
|
||||||
permalinkCreator?: RoomPermalinkCreator;
|
permalinkCreator?: RoomPermalinkCreator;
|
||||||
onFocusChange?: (menuDisplayed: boolean) => void;
|
onFocusChange?: (menuDisplayed: boolean) => void;
|
||||||
|
@ -487,7 +485,7 @@ export default class MessageActionBar extends React.PureComponent<IMessageAction
|
||||||
0,
|
0,
|
||||||
<DownloadActionButton
|
<DownloadActionButton
|
||||||
mxEvent={this.props.mxEvent}
|
mxEvent={this.props.mxEvent}
|
||||||
mediaEventHelperGet={() => this.props.getTile?.().getMediaHelper?.()}
|
mediaEventHelperGet={() => this.props.getTile()?.getMediaHelper?.()}
|
||||||
key="download"
|
key="download"
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
|
|
|
@ -107,6 +107,7 @@ export interface IEventTileOps {
|
||||||
|
|
||||||
export interface IEventTileType extends React.Component {
|
export interface IEventTileType extends React.Component {
|
||||||
getEventTileOps?(): IEventTileOps;
|
getEventTileOps?(): IEventTileOps;
|
||||||
|
getMediaHelper(): MediaEventHelper | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EventTileProps {
|
export interface EventTileProps {
|
||||||
|
|
|
@ -61,7 +61,7 @@ const JoinRuleSettings: React.FC<JoinRuleSettingsProps> = ({
|
||||||
|
|
||||||
const disabled = !room.currentState.mayClientSendStateEvent(EventType.RoomJoinRules, cli);
|
const disabled = !room.currentState.mayClientSendStateEvent(EventType.RoomJoinRules, cli);
|
||||||
|
|
||||||
const [content, setContent] = useLocalEcho<IJoinRuleEventContent | undefined>(
|
const [content, setContent] = useLocalEcho<IJoinRuleEventContent | undefined, IJoinRuleEventContent>(
|
||||||
() => room.currentState.getStateEvents(EventType.RoomJoinRules, "")?.getContent(),
|
() => room.currentState.getStateEvents(EventType.RoomJoinRules, "")?.getContent(),
|
||||||
(content) => cli.sendStateEvent(room.roomId, EventType.RoomJoinRules, content, ""),
|
(content) => cli.sendStateEvent(room.roomId, EventType.RoomJoinRules, content, ""),
|
||||||
onError,
|
onError,
|
||||||
|
|
|
@ -16,13 +16,13 @@ limitations under the License.
|
||||||
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
|
||||||
export const useLocalEcho = <T>(
|
export const useLocalEcho = <T, V extends T = T>(
|
||||||
currentFactory: () => T,
|
currentFactory: () => T,
|
||||||
setterFn: (value: T) => Promise<unknown>,
|
setterFn: (value: V) => Promise<unknown>,
|
||||||
errorFn: (error: unknown) => void,
|
errorFn: (error: unknown) => void,
|
||||||
): [value: T, handler: (value: T) => void] => {
|
): [value: T, handler: (value: V) => void] => {
|
||||||
const [value, setValue] = useState(currentFactory);
|
const [value, setValue] = useState(currentFactory);
|
||||||
const handler = async (value: T): Promise<void> => {
|
const handler = async (value: V): Promise<void> => {
|
||||||
setValue(value);
|
setValue(value);
|
||||||
try {
|
try {
|
||||||
await setterFn(value);
|
await setterFn(value);
|
||||||
|
|
|
@ -25,7 +25,7 @@ import { isLocalRoom } from "../localRoom/isLocalRoom";
|
||||||
import { findDMForUser } from "./findDMForUser";
|
import { findDMForUser } from "./findDMForUser";
|
||||||
import dis from "../../dispatcher/dispatcher";
|
import dis from "../../dispatcher/dispatcher";
|
||||||
import { getAddressType } from "../../UserAddress";
|
import { getAddressType } from "../../UserAddress";
|
||||||
import createRoom from "../../createRoom";
|
import createRoom, { IOpts } from "../../createRoom";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start a DM.
|
* Start a DM.
|
||||||
|
@ -53,7 +53,7 @@ export async function startDm(client: MatrixClient, targets: Member[], showSpinn
|
||||||
return Promise.resolve(existingRoom.roomId);
|
return Promise.resolve(existingRoom.roomId);
|
||||||
}
|
}
|
||||||
|
|
||||||
const createRoomOptions = { inlineErrors: true } as any; // XXX: Type out `createRoomOptions`
|
const createRoomOptions: IOpts = { inlineErrors: true };
|
||||||
|
|
||||||
if (await determineCreateRoomEncryptionOption(client, targets)) {
|
if (await determineCreateRoomEncryptionOption(client, targets)) {
|
||||||
createRoomOptions.encryption = true;
|
createRoomOptions.encryption = true;
|
||||||
|
|
Loading…
Reference in a new issue