Enable @typescript-eslint/explicit-member-accessibility on /src (#9785)

* Enable `@typescript-eslint/explicit-member-accessibility` on /src

* Prettier
This commit is contained in:
Michael Telatynski 2022-12-16 12:29:59 +00:00 committed by GitHub
parent 51554399fb
commit f1e8e7f140
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
396 changed files with 1110 additions and 1098 deletions

View file

@ -42,7 +42,7 @@ export default class AutoDiscoveryUtils {
* @param {string | Error} error The error to check
* @returns {boolean} True if the error is a liveliness error.
*/
static isLivelinessError(error: string | Error): boolean {
public static isLivelinessError(error: string | Error): boolean {
if (!error) return false;
return !!LIVELINESS_DISCOVERY_ERRORS.find((e) =>
typeof error === "string" ? e === error : e === error.message,
@ -57,7 +57,7 @@ export default class AutoDiscoveryUtils {
* implementation for known values.
* @returns {*} The state for the component, given the error.
*/
static authComponentStateForError(err: string | Error | null, pageName = "login"): IAuthComponentState {
public static authComponentStateForError(err: string | Error | null, pageName = "login"): IAuthComponentState {
if (!err) {
return {
serverIsAlive: true,
@ -140,7 +140,7 @@ export default class AutoDiscoveryUtils {
* not be raised.
* @returns {Promise<ValidatedServerConfig>} Resolves to the validated configuration.
*/
static async validateServerConfigWithStaticUrls(
public static async validateServerConfigWithStaticUrls(
homeserverUrl: string,
identityUrl?: string,
syntaxOnly = false,
@ -174,7 +174,7 @@ export default class AutoDiscoveryUtils {
* @param {string} serverName The homeserver domain name (eg: "matrix.org") to validate.
* @returns {Promise<ValidatedServerConfig>} Resolves to the validated configuration.
*/
static async validateServerName(serverName: string): Promise<ValidatedServerConfig> {
public static async validateServerName(serverName: string): Promise<ValidatedServerConfig> {
const result = await AutoDiscovery.findClientConfig(serverName);
return AutoDiscoveryUtils.buildValidatedConfigFromDiscovery(serverName, result);
}
@ -188,7 +188,7 @@ export default class AutoDiscoveryUtils {
* @param {boolean} isSynthetic If true, then the discoveryResult was synthesised locally.
* @returns {Promise<ValidatedServerConfig>} Resolves to the validated configuration.
*/
static buildValidatedConfigFromDiscovery(
public static buildValidatedConfigFromDiscovery(
serverName: string,
discoveryResult,
syntaxOnly = false,

View file

@ -40,7 +40,7 @@ export default class DMRoomMap {
private hasSentOutPatchDirectAccountDataPatch: boolean;
private mDirectEvent: { [key: string]: string[] };
constructor(private readonly matrixClient: MatrixClient) {
public constructor(private readonly matrixClient: MatrixClient) {
// see onAccountData
this.hasSentOutPatchDirectAccountDataPatch = false;

View file

@ -23,7 +23,7 @@ import { IEncryptedFile, IMediaEventInfo } from "../customisations/models/IMedia
import { getBlobSafeMimeType } from "./blobs";
export class DownloadError extends Error {
constructor(e) {
public constructor(e) {
super(e.message);
this.name = "DownloadError";
this.stack = e.stack;
@ -31,7 +31,7 @@ export class DownloadError extends Error {
}
export class DecryptError extends Error {
constructor(e) {
public constructor(e) {
super(e.message);
this.name = "DecryptError";
this.stack = e.stack;

View file

@ -28,7 +28,7 @@ export default class EditorStateTransfer {
private serializedParts: SerializedPart[] = null;
private caret: DocumentOffset = null;
constructor(private readonly event: MatrixEvent) {}
public constructor(private readonly event: MatrixEvent) {}
public setEditorState(caret: DocumentOffset, serializedParts: SerializedPart[]) {
this.caret = caret;

View file

@ -75,7 +75,7 @@ export class FileDownloader {
* @param iframeFn Function to get a pre-configured iframe. Set to null to have the downloader
* use a generic, hidden, iframe.
*/
constructor(private iframeFn: getIframeFn = null) {}
public constructor(private iframeFn: getIframeFn = null) {}
private get iframe(): HTMLIFrameElement {
const iframe = this.iframeFn?.();

View file

@ -28,7 +28,7 @@ export class FixedRollingArray<T> {
* @param width The width of the array.
* @param padValue The value to seed the array with.
*/
constructor(private width: number, padValue: T) {
public constructor(private width: number, padValue: T) {
this.samples = arraySeed(padValue, this.width);
}

View file

@ -30,7 +30,7 @@ export class MarkedExecution {
* @param {Function} onMarkCallback A function that is called when a new mark is made. Not
* called if a mark is already flagged.
*/
constructor(private fn: () => void, private onMarkCallback?: () => void) {}
public constructor(private fn: () => void, private onMarkCallback?: () => void) {}
/**
* Resets the mark without calling the function.

View file

@ -24,13 +24,13 @@ import globToRegexp from "glob-to-regexp";
* for server ACLs and similar functions.
*/
export class MatrixGlob {
_regex: RegExp;
private regex: RegExp;
/**
* Creates a new Matrix Glob
* @param {string} glob The glob to convert. Eg: "*.example.org"
*/
constructor(glob: string) {
public constructor(glob: string) {
const globRegex = globToRegexp(glob, {
extended: false,
globstar: false,
@ -39,7 +39,7 @@ export class MatrixGlob {
// We need to convert `?` manually because globToRegexp's extended mode
// does more than we want it to.
const replaced = globRegex.toString().replace(/\\\?/g, ".");
this._regex = new RegExp(replaced.substring(1, replaced.length - 1));
this.regex = new RegExp(replaced.substring(1, replaced.length - 1));
}
/**
@ -47,7 +47,7 @@ export class MatrixGlob {
* @param {string} val The value to test.
* @returns {boolean} True if the value matches the glob, false otherwise.
*/
test(val: string): boolean {
return this._regex.test(val);
public test(val: string): boolean {
return this.regex.test(val);
}
}

View file

@ -64,7 +64,7 @@ export default class MultiInviter {
* @param {string} roomId The ID of the room to invite to
* @param {function} progressCallback optional callback, fired after each invite.
*/
constructor(private roomId: string, private readonly progressCallback?: () => void) {
public constructor(private roomId: string, private readonly progressCallback?: () => void) {
this.matrixClient = MatrixClientPeg.get();
}

View file

@ -22,7 +22,7 @@ export default class PinningUtils {
/**
* Event types that may be pinned.
*/
static pinnableEventTypes: (EventType | string)[] = [
public static pinnableEventTypes: (EventType | string)[] = [
EventType.RoomMessage,
M_POLL_START.name,
M_POLL_START.altName,
@ -33,7 +33,7 @@ export default class PinningUtils {
* @param {MatrixEvent} event The event to check.
* @return {boolean} True if the event may be pinned, false otherwise.
*/
static isPinnable(event: MatrixEvent): boolean {
public static isPinnable(event: MatrixEvent): boolean {
if (!event) return false;
if (!this.pinnableEventTypes.includes(event.getType())) return false;
if (event.isRedacted()) return false;

View file

@ -32,7 +32,7 @@ export default class Timer {
private resolve: () => void;
private reject: (Error) => void;
constructor(private timeout: number) {
public constructor(private timeout: number) {
this.setNotStarted();
}
@ -59,7 +59,7 @@ export default class Timer {
}
};
changeTimeout(timeout: number) {
public changeTimeout(timeout: number) {
if (timeout === this.timeout) {
return;
}
@ -75,7 +75,7 @@ export default class Timer {
* if not started before, starts the timer.
* @returns {Timer} the same timer
*/
start() {
public start() {
if (!this.isRunning()) {
this.startTs = Date.now();
this.timerHandle = window.setTimeout(this.onTimeout, this.timeout);
@ -87,7 +87,7 @@ export default class Timer {
* (re)start the timer. If it's running, reset the timeout. If not, start it.
* @returns {Timer} the same timer
*/
restart() {
public restart() {
if (this.isRunning()) {
// don't clearTimeout here as this method
// can be called in fast succession,
@ -105,7 +105,7 @@ export default class Timer {
* and reject the promise for this timer.
* @returns {Timer} the same timer
*/
abort() {
public abort() {
if (this.isRunning()) {
clearTimeout(this.timerHandle);
this.reject(new Error("Timer was aborted."));
@ -119,11 +119,11 @@ export default class Timer {
*or is rejected when abort is called
*@return {Promise}
*/
finished() {
public finished() {
return this.promise;
}
isRunning() {
public isRunning() {
return this.timerHandle !== null;
}
}

View file

@ -15,15 +15,15 @@ limitations under the License.
*/
export class ValidatedServerConfig {
hsUrl: string;
hsName: string;
hsNameIsDifferent: string;
public hsUrl: string;
public hsName: string;
public hsNameIsDifferent: string;
isUrl: string;
public isUrl: string;
isDefault: boolean;
public isDefault: boolean;
// when the server config is based on static URLs the hsName is not resolvable and things may wish to use hsUrl
isNameResolvable: boolean;
public isNameResolvable: boolean;
warning: string;
public warning: string;
}

View file

@ -57,7 +57,7 @@ export default class WidgetUtils {
* @return Boolean -- true if the user can modify widgets in this room
* @throws Error -- specifies the error reason
*/
static canUserModifyWidgets(roomId: string): boolean {
public static canUserModifyWidgets(roomId: string): boolean {
if (!roomId) {
logger.warn("No room ID specified");
return false;
@ -96,7 +96,7 @@ export default class WidgetUtils {
* @param {[type]} testUrlString URL to check
* @return {Boolean} True if specified URL is a scalar URL
*/
static isScalarUrl(testUrlString: string): boolean {
public static isScalarUrl(testUrlString: string): boolean {
if (!testUrlString) {
logger.error("Scalar URL check failed. No URL specified");
return false;
@ -139,7 +139,7 @@ export default class WidgetUtils {
* @returns {Promise} that resolves when the widget is in the
* requested state according to the `add` param
*/
static waitForUserWidget(widgetId: string, add: boolean): Promise<void> {
public static waitForUserWidget(widgetId: string, add: boolean): Promise<void> {
return new Promise((resolve, reject) => {
// Tests an account data event, returning true if it's in the state
// we're waiting for it to be in
@ -186,7 +186,7 @@ export default class WidgetUtils {
* @returns {Promise} that resolves when the widget is in the
* requested state according to the `add` param
*/
static waitForRoomWidget(widgetId: string, roomId: string, add: boolean): Promise<void> {
public static waitForRoomWidget(widgetId: string, roomId: string, add: boolean): Promise<void> {
return new Promise((resolve, reject) => {
// Tests a list of state events, returning true if it's in the state
// we're waiting for it to be in
@ -229,7 +229,7 @@ export default class WidgetUtils {
});
}
static setUserWidget(
public static setUserWidget(
widgetId: string,
widgetType: WidgetType,
widgetUrl: string,
@ -282,7 +282,7 @@ export default class WidgetUtils {
});
}
static setRoomWidget(
public static setRoomWidget(
roomId: string,
widgetId: string,
widgetType?: WidgetType,
@ -312,7 +312,7 @@ export default class WidgetUtils {
return WidgetUtils.setRoomWidgetContent(roomId, widgetId, content);
}
static setRoomWidgetContent(roomId: string, widgetId: string, content: IWidget) {
public static setRoomWidgetContent(roomId: string, widgetId: string, content: IWidget) {
const addingWidget = !!content.url;
WidgetEchoStore.setRoomWidgetEcho(roomId, widgetId, content);
@ -334,7 +334,7 @@ export default class WidgetUtils {
* @param {Room} room The room to get widgets force
* @return {[object]} Array containing current / active room widgets
*/
static getRoomWidgets(room: Room) {
public static getRoomWidgets(room: Room) {
// TODO: Enable support for m.widget event type (https://github.com/vector-im/element-web/issues/13111)
const appsStateEvents = room.currentState.getStateEvents("im.vector.modular.widgets");
if (!appsStateEvents) {
@ -350,7 +350,7 @@ export default class WidgetUtils {
* Get user specific widgets (not linked to a specific room)
* @return {object} Event content object containing current / active user widgets
*/
static getUserWidgets(): Record<string, IWidgetEvent> {
public static getUserWidgets(): Record<string, IWidgetEvent> {
const client = MatrixClientPeg.get();
if (!client) {
throw new Error("User not logged in");
@ -366,7 +366,7 @@ export default class WidgetUtils {
* Get user specific widgets (not linked to a specific room) as an array
* @return {[object]} Array containing current / active user widgets
*/
static getUserWidgetsArray(): IWidgetEvent[] {
public static getUserWidgetsArray(): IWidgetEvent[] {
return Object.values(WidgetUtils.getUserWidgets());
}
@ -374,7 +374,7 @@ export default class WidgetUtils {
* Get active stickerpicker widgets (stickerpickers are user widgets by nature)
* @return {[object]} Array containing current / active stickerpicker widgets
*/
static getStickerpickerWidgets(): IWidgetEvent[] {
public static getStickerpickerWidgets(): IWidgetEvent[] {
const widgets = WidgetUtils.getUserWidgetsArray();
return widgets.filter((widget) => widget.content && widget.content.type === "m.stickerpicker");
}
@ -383,12 +383,12 @@ export default class WidgetUtils {
* Get all integration manager widgets for this user.
* @returns {Object[]} An array of integration manager user widgets.
*/
static getIntegrationManagerWidgets(): IWidgetEvent[] {
public static getIntegrationManagerWidgets(): IWidgetEvent[] {
const widgets = WidgetUtils.getUserWidgetsArray();
return widgets.filter((w) => w.content && w.content.type === "m.integration_manager");
}
static getRoomWidgetsOfType(room: Room, type: WidgetType): MatrixEvent[] {
public static getRoomWidgetsOfType(room: Room, type: WidgetType): MatrixEvent[] {
const widgets = WidgetUtils.getRoomWidgets(room) || [];
return widgets.filter((w) => {
const content = w.getContent();
@ -396,7 +396,7 @@ export default class WidgetUtils {
});
}
static async removeIntegrationManagerWidgets(): Promise<void> {
public static async removeIntegrationManagerWidgets(): Promise<void> {
const client = MatrixClientPeg.get();
if (!client) {
throw new Error("User not logged in");
@ -412,7 +412,7 @@ export default class WidgetUtils {
await client.setAccountData("m.widgets", userWidgets);
}
static addIntegrationManagerWidget(name: string, uiUrl: string, apiUrl: string): Promise<void> {
public static addIntegrationManagerWidget(name: string, uiUrl: string, apiUrl: string): Promise<void> {
return WidgetUtils.setUserWidget(
"integration_manager_" + new Date().getTime(),
WidgetType.INTEGRATION_MANAGER,
@ -426,7 +426,7 @@ export default class WidgetUtils {
* Remove all stickerpicker widgets (stickerpickers are user widgets by nature)
* @return {Promise} Resolves on account data updated
*/
static async removeStickerpickerWidgets(): Promise<void> {
public static async removeStickerpickerWidgets(): Promise<void> {
const client = MatrixClientPeg.get();
if (!client) {
throw new Error("User not logged in");
@ -442,7 +442,7 @@ export default class WidgetUtils {
await client.setAccountData("m.widgets", userWidgets);
}
static async addJitsiWidget(
public static async addJitsiWidget(
roomId: string,
type: CallType,
name: string,
@ -480,7 +480,7 @@ export default class WidgetUtils {
});
}
static makeAppConfig(
public static makeAppConfig(
appId: string,
app: Partial<IApp>,
senderUserId: string,
@ -500,7 +500,7 @@ export default class WidgetUtils {
return app as IApp;
}
static getLocalJitsiWrapperUrl(opts: { forLocalRender?: boolean; auth?: string } = {}) {
public static getLocalJitsiWrapperUrl(opts: { forLocalRender?: boolean; auth?: string } = {}) {
// NB. we can't just encodeURIComponent all of these because the $ signs need to be there
const queryStringParts = [
"conferenceDomain=$domain",
@ -534,30 +534,30 @@ export default class WidgetUtils {
return url.href;
}
static getWidgetName(app?: IApp): string {
public static getWidgetName(app?: IApp): string {
return app?.name?.trim() || _t("Unknown App");
}
static getWidgetDataTitle(app?: IApp): string {
public static getWidgetDataTitle(app?: IApp): string {
return app?.data?.title?.trim() || "";
}
static getWidgetUid(app?: IApp): string {
public static getWidgetUid(app?: IApp): string {
return app ? WidgetUtils.calcWidgetUid(app.id, app.roomId) : "";
}
static calcWidgetUid(widgetId: string, roomId?: string): string {
public static calcWidgetUid(widgetId: string, roomId?: string): string {
return roomId ? `room_${roomId}_${widgetId}` : `user_${widgetId}`;
}
static editWidget(room: Room, app: IApp): void {
public static editWidget(room: Room, app: IApp): void {
// noinspection JSIgnoredPromiseFromCall
IntegrationManagers.sharedInstance()
.getPrimaryManager()
.open(room, "type_" + app.type, app.id);
}
static isManagedByManager(app) {
public static isManagedByManager(app) {
if (WidgetUtils.isScalarUrl(app.url)) {
const managers = IntegrationManagers.sharedInstance();
if (managers.hasManager()) {

View file

@ -248,7 +248,7 @@ export class ArrayUtil<T> {
* Create a new array helper.
* @param a The array to help. Can be modified in-place.
*/
constructor(private a: T[]) {}
public constructor(private a: T[]) {}
/**
* The value of this array, after all appropriate alterations.
@ -281,7 +281,7 @@ export class GroupedArray<K, T> {
* Creates a new group helper.
* @param val The group to help. Can be modified in-place.
*/
constructor(private val: Map<K, T[]>) {}
public constructor(private val: Map<K, T[]>) {}
/**
* The value of this group, after all applicable alterations.

View file

@ -111,7 +111,7 @@ export class DirectoryMember extends Member {
private readonly avatarUrl?: string;
// eslint-disable-next-line camelcase
constructor(userDirResult: { user_id: string; display_name?: string; avatar_url?: string }) {
public constructor(userDirResult: { user_id: string; display_name?: string; avatar_url?: string }) {
super();
this._userId = userDirResult.user_id;
this.displayName = userDirResult.display_name;
@ -119,15 +119,15 @@ export class DirectoryMember extends Member {
}
// These next class members are for the Member interface
get name(): string {
public get name(): string {
return this.displayName || this._userId;
}
get userId(): string {
public get userId(): string {
return this._userId;
}
getMxcAvatarUrl(): string {
public getMxcAvatarUrl(): string {
return this.avatarUrl;
}
}
@ -135,7 +135,7 @@ export class DirectoryMember extends Member {
export class ThreepidMember extends Member {
private readonly id: string;
constructor(id: string) {
public constructor(id: string) {
super();
this.id = id;
}
@ -143,20 +143,20 @@ export class ThreepidMember extends Member {
// This is a getter that would be falsy on all other implementations. Until we have
// better type support in the react-sdk we can use this trick to determine the kind
// of 3PID we're dealing with, if any.
get isEmail(): boolean {
public get isEmail(): boolean {
return this.id.includes("@");
}
// These next class members are for the Member interface
get name(): string {
public get name(): string {
return this.id;
}
get userId(): string {
public get userId(): string {
return this.id;
}
getMxcAvatarUrl(): string {
public getMxcAvatarUrl(): string {
return null;
}
}

View file

@ -15,7 +15,7 @@ limitations under the License.
*/
export class GenericError extends Error {
constructor(public readonly message: string, public readonly description?: string | undefined) {
public constructor(public readonly message: string, public readonly description?: string | undefined) {
super(message);
}
}

View file

@ -287,5 +287,5 @@ export default abstract class Exporter {
return mxEv.getType() === attachmentTypes[0] || attachmentTypes.includes(mxEv.getContent().msgtype);
}
abstract export(): Promise<void>;
public abstract export(): Promise<void>;
}

View file

@ -49,7 +49,7 @@ export default class HTMLExporter extends Exporter {
protected mediaOmitText: string;
private threadsEnabled: boolean;
constructor(
public constructor(
room: Room,
exportType: ExportType,
exportOptions: IExportOptions,

View file

@ -29,7 +29,7 @@ export default class JSONExporter extends Exporter {
protected totalSize = 0;
protected messages: Record<string, any>[] = [];
constructor(
public constructor(
room: Room,
exportType: ExportType,
exportOptions: IExportOptions,

View file

@ -29,7 +29,7 @@ export default class PlainTextExporter extends Exporter {
protected totalSize: number;
protected mediaOmitText: string;
constructor(
public constructor(
room: Room,
exportType: ExportType,
exportOptions: IExportOptions,

View file

@ -22,7 +22,7 @@ import PermalinkConstructor, { PermalinkParts } from "./PermalinkConstructor";
export default class ElementPermalinkConstructor extends PermalinkConstructor {
private elementUrl: string;
constructor(elementUrl: string) {
public constructor(elementUrl: string) {
super();
this.elementUrl = elementUrl;
@ -31,19 +31,19 @@ export default class ElementPermalinkConstructor extends PermalinkConstructor {
}
}
forEvent(roomId: string, eventId: string, serverCandidates: string[]): string {
public forEvent(roomId: string, eventId: string, serverCandidates: string[]): string {
return `${this.elementUrl}/#/room/${roomId}/${eventId}${this.encodeServerCandidates(serverCandidates)}`;
}
forRoom(roomIdOrAlias: string, serverCandidates?: string[]): string {
public forRoom(roomIdOrAlias: string, serverCandidates?: string[]): string {
return `${this.elementUrl}/#/room/${roomIdOrAlias}${this.encodeServerCandidates(serverCandidates)}`;
}
forUser(userId: string): string {
public forUser(userId: string): string {
return `${this.elementUrl}/#/user/${userId}`;
}
forEntity(entityId: string): string {
public forEntity(entityId: string): string {
if (entityId[0] === "!" || entityId[0] === "#") {
return this.forRoom(entityId);
} else if (entityId[0] === "@") {
@ -51,12 +51,12 @@ export default class ElementPermalinkConstructor extends PermalinkConstructor {
} else throw new Error("Unrecognized entity");
}
isPermalinkHost(testHost: string): boolean {
public isPermalinkHost(testHost: string): boolean {
const parsedUrl = new URL(this.elementUrl);
return testHost === (parsedUrl.host || parsedUrl.hostname); // one of the hosts should match
}
encodeServerCandidates(candidates?: string[]) {
public encodeServerCandidates(candidates?: string[]) {
if (!candidates || candidates.length === 0) return "";
return `?via=${candidates.map((c) => encodeURIComponent(c)).join("&via=")}`;
}
@ -64,7 +64,7 @@ export default class ElementPermalinkConstructor extends PermalinkConstructor {
// Heavily inspired by/borrowed from the matrix-bot-sdk (with permission):
// https://github.com/turt2live/matrix-js-bot-sdk/blob/7c4665c9a25c2c8e0fe4e509f2616505b5b66a1c/src/Permalinks.ts#L33-L61
// Adapted for Element's URL format
parsePermalink(fullUrl: string): PermalinkParts {
public parsePermalink(fullUrl: string): PermalinkParts {
if (!fullUrl || !fullUrl.startsWith(this.elementUrl)) {
throw new Error("Does not appear to be a permalink");
}
@ -79,7 +79,7 @@ export default class ElementPermalinkConstructor extends PermalinkConstructor {
* @param {string} route The app route
* @returns {PermalinkParts}
*/
static parseAppRoute(route: string): PermalinkParts {
public static parseAppRoute(route: string): PermalinkParts {
const parts = route.split("/");
if (parts.length < 2) {

View file

@ -20,7 +20,7 @@ import PermalinkConstructor, { PermalinkParts } from "./PermalinkConstructor";
* Generates matrix: scheme permalinks
*/
export default class MatrixSchemePermalinkConstructor extends PermalinkConstructor {
constructor() {
public constructor() {
super();
}
@ -38,36 +38,36 @@ export default class MatrixSchemePermalinkConstructor extends PermalinkConstruct
throw new Error("Cannot encode entity: " + entity);
}
forEvent(roomId: string, eventId: string, serverCandidates: string[]): string {
public forEvent(roomId: string, eventId: string, serverCandidates: string[]): string {
return (
`matrix:${this.encodeEntity(roomId)}` +
`/${this.encodeEntity(eventId)}${this.encodeServerCandidates(serverCandidates)}`
);
}
forRoom(roomIdOrAlias: string, serverCandidates: string[]): string {
public forRoom(roomIdOrAlias: string, serverCandidates: string[]): string {
return `matrix:${this.encodeEntity(roomIdOrAlias)}${this.encodeServerCandidates(serverCandidates)}`;
}
forUser(userId: string): string {
public forUser(userId: string): string {
return `matrix:${this.encodeEntity(userId)}`;
}
forEntity(entityId: string): string {
public forEntity(entityId: string): string {
return `matrix:${this.encodeEntity(entityId)}`;
}
isPermalinkHost(testHost: string): boolean {
public isPermalinkHost(testHost: string): boolean {
// TODO: Change API signature to accept the URL for checking
return testHost === "";
}
encodeServerCandidates(candidates: string[]) {
public encodeServerCandidates(candidates: string[]) {
if (!candidates || candidates.length === 0) return "";
return `?via=${candidates.map((c) => encodeURIComponent(c)).join("&via=")}`;
}
parsePermalink(fullUrl: string): PermalinkParts {
public parsePermalink(fullUrl: string): PermalinkParts {
if (!fullUrl || !fullUrl.startsWith("matrix:")) {
throw new Error("Does not appear to be a permalink");
}

View file

@ -23,38 +23,38 @@ export const baseUrl = `https://${host}`;
* Generates matrix.to permalinks
*/
export default class MatrixToPermalinkConstructor extends PermalinkConstructor {
constructor() {
public constructor() {
super();
}
forEvent(roomId: string, eventId: string, serverCandidates: string[]): string {
public forEvent(roomId: string, eventId: string, serverCandidates: string[]): string {
return `${baseUrl}/#/${roomId}/${eventId}${this.encodeServerCandidates(serverCandidates)}`;
}
forRoom(roomIdOrAlias: string, serverCandidates: string[]): string {
public forRoom(roomIdOrAlias: string, serverCandidates: string[]): string {
return `${baseUrl}/#/${roomIdOrAlias}${this.encodeServerCandidates(serverCandidates)}`;
}
forUser(userId: string): string {
public forUser(userId: string): string {
return `${baseUrl}/#/${userId}`;
}
forEntity(entityId: string): string {
public forEntity(entityId: string): string {
return `${baseUrl}/#/${entityId}`;
}
isPermalinkHost(testHost: string): boolean {
public isPermalinkHost(testHost: string): boolean {
return testHost === host;
}
encodeServerCandidates(candidates: string[]) {
public encodeServerCandidates(candidates: string[]) {
if (!candidates || candidates.length === 0) return "";
return `?via=${candidates.map((c) => encodeURIComponent(c)).join("&via=")}`;
}
// Heavily inspired by/borrowed from the matrix-bot-sdk (with permission):
// https://github.com/turt2live/matrix-js-bot-sdk/blob/7c4665c9a25c2c8e0fe4e509f2616505b5b66a1c/src/Permalinks.ts#L33-L61
parsePermalink(fullUrl: string): PermalinkParts {
public parsePermalink(fullUrl: string): PermalinkParts {
if (!fullUrl || !fullUrl.startsWith(baseUrl)) {
throw new Error("Does not appear to be a permalink");
}

View file

@ -19,27 +19,27 @@ limitations under the License.
* TODO: Convert this to a real TypeScript interface
*/
export default class PermalinkConstructor {
forEvent(roomId: string, eventId: string, serverCandidates: string[] = []): string {
public forEvent(roomId: string, eventId: string, serverCandidates: string[] = []): string {
throw new Error("Not implemented");
}
forRoom(roomIdOrAlias: string, serverCandidates: string[] = []): string {
public forRoom(roomIdOrAlias: string, serverCandidates: string[] = []): string {
throw new Error("Not implemented");
}
forUser(userId: string): string {
public forUser(userId: string): string {
throw new Error("Not implemented");
}
forEntity(entityId: string): string {
public forEntity(entityId: string): string {
throw new Error("Not implemented");
}
isPermalinkHost(host: string): boolean {
public isPermalinkHost(host: string): boolean {
throw new Error("Not implemented");
}
parsePermalink(fullUrl: string): PermalinkParts {
public parsePermalink(fullUrl: string): PermalinkParts {
throw new Error("Not implemented");
}
}
@ -47,35 +47,30 @@ export default class PermalinkConstructor {
// Inspired by/Borrowed with permission from the matrix-bot-sdk:
// https://github.com/turt2live/matrix-js-bot-sdk/blob/7c4665c9a25c2c8e0fe4e509f2616505b5b66a1c/src/Permalinks.ts#L1-L6
export class PermalinkParts {
roomIdOrAlias: string;
eventId: string;
userId: string;
viaServers: string[];
public constructor(
public readonly roomIdOrAlias: string,
public readonly eventId: string,
public readonly userId: string,
public readonly viaServers: string[],
) {}
constructor(roomIdOrAlias: string, eventId: string, userId: string, viaServers: string[]) {
this.roomIdOrAlias = roomIdOrAlias;
this.eventId = eventId;
this.userId = userId;
this.viaServers = viaServers;
}
static forUser(userId: string): PermalinkParts {
public static forUser(userId: string): PermalinkParts {
return new PermalinkParts(null, null, userId, null);
}
static forRoom(roomIdOrAlias: string, viaServers: string[] = []): PermalinkParts {
public static forRoom(roomIdOrAlias: string, viaServers: string[] = []): PermalinkParts {
return new PermalinkParts(roomIdOrAlias, null, null, viaServers);
}
static forEvent(roomId: string, eventId: string, viaServers: string[] = []): PermalinkParts {
public static forEvent(roomId: string, eventId: string, viaServers: string[] = []): PermalinkParts {
return new PermalinkParts(roomId, eventId, null, viaServers);
}
get primaryEntityId(): string {
public get primaryEntityId(): string {
return this.roomIdOrAlias || this.userId;
}
get sigil(): string {
public get sigil(): string {
return this.primaryEntityId[0];
}
}

View file

@ -94,7 +94,7 @@ export class RoomPermalinkCreator {
// Some of the tests done by this class are relatively expensive, so normally
// throttled to not happen on every update. Pass false as the shouldThrottle
// param to disable this behaviour, eg. for tests.
constructor(room: Room, roomId: string | null = null, shouldThrottle = true) {
public constructor(room: Room, roomId: string | null = null, shouldThrottle = true) {
this.room = room;
this.roomId = room ? room.roomId : roomId;
this.highestPlUserId = null;