use eslint to format ts files.

This commit is contained in:
wuyudi 2023-02-08 02:20:48 +09:00
parent 641714285a
commit 34489bfb30
14 changed files with 117 additions and 303 deletions

View file

@ -57,5 +57,6 @@ module.exports = {
"@typescript-eslint/no-unused-vars": "error",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/ban-types": "off",
},
};

View file

@ -1,5 +1,11 @@
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"typescript.tsdk": "node_modules/typescript/lib"
"typescript.tsdk": "node_modules/typescript/lib",
"[typescript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
},
"[javascript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
}
}

View file

@ -1,4 +1,5 @@
import EventEmitter from 'events';
import { MatrixClient, MatrixEvent, NotificationCountType, Room } from 'matrix-js-sdk';
import renderAvatar from '../../app/atoms/avatar/render';
import { cssColorMXID } from '../../util/colorMXID';
import { selectRoom } from '../action/navigation';
@ -11,7 +12,6 @@ import LogoSVG from '../../../public/res/svg/cinny.svg';
import LogoUnreadSVG from '../../../public/res/svg/cinny-unread.svg';
import LogoHighlightSVG from '../../../public/res/svg/cinny-highlight.svg';
import { html, plain } from '../../util/markdown';
import { MatrixClient, MatrixEvent, NotificationCountType, Room } from 'matrix-js-sdk';
import RoomList from './RoomList';
function isNotifEvent(mEvent: MatrixEvent) {
@ -35,14 +35,23 @@ function findMutedRule(overrideRules, roomId) {
class Notifications extends EventEmitter {
initialized: boolean;
favicon: string;
matrixClient: MatrixClient;
roomList: RoomList;
roomIdToNoti: Map<string, any>;
roomIdToPopupNotis: Map<string, any>;
eventIdToPopupNoti: Map<any, any>;
_notiAudio: any;
_inviteAudio: any;
constructor(roomList) {
super();
@ -333,7 +342,7 @@ class Notifications extends EventEmitter {
}
_listenEvents() {
//@ts-ignore
// @ts-ignore
this.matrixClient.on('Room.timeline', (mEvent: MatrixEvent, room: Room) => {
if (mEvent.isRedaction()) this._deletePopupNoti(mEvent.event.redacts);
@ -360,7 +369,7 @@ class Notifications extends EventEmitter {
this._displayPopupNoti(mEvent, room);
}
});
//@ts-ignore
// @ts-ignore
this.matrixClient.on('accountData', (mEvent: MatrixEvent, oldMEvent: MatrixEvent) => {
if (mEvent.getType() === 'm.push_rules') {
const override = mEvent?.getContent()?.global?.override;
@ -397,7 +406,7 @@ class Notifications extends EventEmitter {
});
}
});
//@ts-ignore
// @ts-ignore
this.matrixClient.on('Room.receipt', (mEvent: MatrixEvent, room: Room) => {
if (mEvent.getType() === 'm.receipt') {
if (room.isSpaceRoom()) return;
@ -411,7 +420,7 @@ class Notifications extends EventEmitter {
this._deletePopupRoomNotis(room.roomId);
}
});
//@ts-ignore
// @ts-ignore
this.matrixClient.on('Room.myMembership', (room: Room, membership) => {
if (membership === 'leave' && this.hasNoti(room.roomId)) {
this.deleteNoti(room.roomId);

View file

@ -5,7 +5,6 @@ import {
MatrixClient,
MatrixEvent,
Room,
TimelineIndex,
} from 'matrix-js-sdk';
import initMatrix from '../initMatrix';
import cons from './cons';
@ -53,18 +52,18 @@ function addToMap(myMap: Map<string, MatrixEvent[]>, mEvent: MatrixEvent) {
function getFirstLinkedTimeline(timeline: EventTimeline) {
let tm = timeline;
//@ts-ignore
// @ts-ignore
while (tm.prevTimeline) {
//@ts-ignore
// @ts-ignore
tm = tm.prevTimeline;
}
return tm;
}
function getLastLinkedTimeline(timeline: EventTimeline) {
let tm = timeline;
//@ts-ignore
// @ts-ignore
while (tm.nextTimeline) {
//@ts-ignore
// @ts-ignore
tm = tm.nextTimeline;
}
return tm;
@ -78,9 +77,9 @@ function iterateLinkedTimelines(
let tm = timeline;
while (tm) {
callback(tm);
//@ts-ignore
// @ts-ignore
if (backwards) tm = tm.prevTimeline;
//@ts-ignore
// @ts-ignore
else tm = tm.nextTimeline;
}
}
@ -89,7 +88,7 @@ function isTimelineLinked(tm1: EventTimeline, tm2: EventTimeline) {
let tm = getFirstLinkedTimeline(tm1);
while (tm) {
if (tm === tm2) return true;
//@ts-ignore
// @ts-ignore
tm = tm.nextTimeline;
}
return false;
@ -97,17 +96,29 @@ function isTimelineLinked(tm1: EventTimeline, tm2: EventTimeline) {
class RoomTimeline extends EventEmitter {
timeline: any[];
editedTimeline: Map<any, any>;
reactionTimeline: Map<any, any>;
typingMembers: Set<unknown>;
matrixClient: MatrixClient;
roomId: string;
room: any;
liveTimeline;
activeTimeline: any;
isOngoingPagination: boolean;
ongoingDecryptionCount: number;
initialized: boolean;
_listenRoomTimeline: (
event: any,
room: any,
@ -115,10 +126,15 @@ class RoomTimeline extends EventEmitter {
removed: any,
data: any
) => void;
_listenDecryptEvent: (event: any) => void;
_listenRedaction: (mEvent: MatrixEvent, room: any) => void;
_listenTypingEvent: (event: any, member: any) => void;
_listenReciptEvent: (event: any, room: any) => void;
constructor(roomId: string) {
super();
// These are local timelines
@ -141,7 +157,7 @@ class RoomTimeline extends EventEmitter {
setTimeout(() => this.room.loadMembersIfNeeded());
// TODO: remove below line
//@ts-ignore
// @ts-ignore
window.selectedRoom = this;
}
@ -440,29 +456,29 @@ class RoomTimeline extends EventEmitter {
this.emit(cons.events.roomTimeline.LIVE_RECEIPT);
}
};
//@ts-ignore
// @ts-ignore
this.matrixClient.on('Room.timeline', this._listenRoomTimeline);
//@ts-ignore
// @ts-ignore
this.matrixClient.on('Room.redaction', this._listenRedaction);
//@ts-ignore
// @ts-ignore
this.matrixClient.on('Event.decrypted', this._listenDecryptEvent);
//@ts-ignore
// @ts-ignore
this.matrixClient.on('RoomMember.typing', this._listenTypingEvent);
//@ts-ignore
// @ts-ignore
this.matrixClient.on('Room.receipt', this._listenReciptEvent);
}
removeInternalListeners() {
if (!this.initialized) return;
//@ts-ignore
// @ts-ignore
this.matrixClient.removeListener('Room.timeline', this._listenRoomTimeline);
//@ts-ignore
// @ts-ignore
this.matrixClient.removeListener('Room.redaction', this._listenRedaction);
//@ts-ignore
// @ts-ignore
this.matrixClient.removeListener('Event.decrypted', this._listenDecryptEvent);
//@ts-ignore
// @ts-ignore
this.matrixClient.removeListener('RoomMember.typing', this._listenTypingEvent);
//@ts-ignore
// @ts-ignore
this.matrixClient.removeListener('Room.receipt', this._listenReciptEvent);
}
}

View file

@ -3,10 +3,15 @@ import { RoomHierarchy } from 'matrix-js-sdk/lib/room-hierarchy';
class RoomsHierarchy {
matrixClient: MatrixClient;
_maxDepth: number;
_suggestedOnly: boolean;
_limit: number;
roomIdToHierarchy: Map<any, any>;
constructor(matrixClient: MatrixClient, limit = 20, maxDepth = 1, suggestedOnly = false) {
this.matrixClient = matrixClient;
this._maxDepth = maxDepth;

View file

@ -1,17 +1,18 @@
import EventEmitter from 'events';
import encrypt from 'browser-encrypt-attachment';
import { encode } from 'blurhash';
import { IContent, MatrixClient, MatrixEvent } from 'matrix-js-sdk';
import { getShortcodeToEmoji } from '../../app/organisms/emoji-board/custom-emoji';
import { getBlobSafeMimeType } from '../../util/mimetypes';
import { sanitizeText } from '../../util/sanitize';
import cons from './cons';
import settings from './settings';
import { markdown, plain } from '../../util/markdown';
import { IContent, MatrixClient, MatrixEvent } from 'matrix-js-sdk';
import RoomList from './RoomList';
const blurhashField = 'xyz.amorgan.blurhash';
// eslint-disable-next-line no-undef
function encodeBlurhash(img: CanvasImageSource) {
const canvas = document.createElement('canvas');
canvas.width = 100;
@ -66,6 +67,7 @@ function loadVideo(videoFile: Blob) {
});
}
function getVideoThumbnail(
// eslint-disable-next-line no-undef
video: CanvasImageSource,
width: number,
height: number,
@ -107,8 +109,11 @@ function getVideoThumbnail(
class RoomsInput extends EventEmitter {
matrixClient: MatrixClient;
roomList: RoomList;
roomIdToInput: Map<any, any>;
constructor(mx: MatrixClient, roomList: RoomList) {
super();
@ -221,7 +226,7 @@ class RoomsInput extends EventEmitter {
const autoMarkdown = options?.autoMarkdown ?? true;
const room = this.matrixClient.getRoom(roomId);
//@ts-ignore
// @ts-ignore
const userNames = room.currentState.userIdsToDisplayNames;
const parentIds = this.roomList.getAllParentSpaces(room.roomId);
const parentRooms = [...parentIds].map((id) => this.matrixClient.getRoom(id));

View file

@ -1,5 +1,5 @@
import EventEmitter from 'events';
import { MatrixClient, Room } from 'matrix-js-sdk';
import { MatrixClient } from 'matrix-js-sdk';
import appDispatcher from '../dispatcher';
import AccountData from './AccountData';
import cons from './cons';
@ -7,18 +7,27 @@ import RoomList from './RoomList';
class Navigation extends EventEmitter {
initMatrix: { roomList: RoomList; accountData: AccountData; matrixClient: MatrixClient };
selectedTab: string;
selectedSpaceId: string;
selectedSpacePath: string[];
selectedRoomId: string;
isRoomSettings: boolean;
recentRooms: string[];
spaceToRoom: Map<string, any>;
rawModelStack: any[];
constructor() {
super();
// this will attached by initMatrix
//@ts-ignore
// @ts-ignore
this.initMatrix = {};
this.selectedTab = cons.tabs.HOME;

View file

@ -16,7 +16,7 @@ export function getPrivateKey(keyId) {
}
export function deletePrivateKey(keyId) {
//@ts-ignore
// @ts-ignore
delete secretStorageKeys.delete(keyId);
}

View file

@ -3,6 +3,7 @@ import appDispatcher from '../dispatcher';
import cons from './cons';
// eslint-disable-next-line no-use-before-define
function getSettings(): Settings {
const settings = localStorage.getItem('settings');
if (settings === null) return null;
@ -11,6 +12,7 @@ function getSettings(): Settings {
function setSettings(key: string, value) {
let settings = getSettings();
// eslint-disable-next-line no-use-before-define
if (settings === null) settings = new Settings();
settings[key] = value;
localStorage.setItem('settings', JSON.stringify(settings));
@ -18,15 +20,25 @@ function setSettings(key: string, value) {
class Settings extends EventEmitter {
themes: string[];
themeIndex: number;
useSystemTheme: boolean;
isMarkdown: boolean;
isPeopleDrawer: boolean;
hideMembershipEvents: boolean;
hideNickAvatarEvents: boolean;
_showNotifications: boolean;
isNotificationSounds: boolean;
isTouchScreenDevice: boolean;
constructor() {
super();

View file

@ -2,17 +2,29 @@ import EventEmitter from 'events';
class AsyncSearch extends EventEmitter {
RESULT_SENT: string;
dataList: (string | object)[];
term: any;
searchKeys: any;
isContain: boolean;
isCaseSensitive: boolean;
normalizeUnicode: boolean;
ignoreWhitespace: boolean;
limit: number;
findingList: any[];
searchUptoIndex: number;
sessionStartTimestamp: number;
constructor() {
super();

View file

@ -1,5 +1,6 @@
class Postie {
_topics: Map<string, Map<string, Set<Function>>>;
constructor() {
this._topics = new Map();
}
@ -78,7 +79,7 @@ class Postie {
* @param {*} data - Data to deliver to subscriber
*/
post(topic: string, address: string | string[], data: any) {
const sendPost = (inboxes: Set<Function>, addr: string) => {
const sendPost = (inboxes: Set<Function>, addr: string) => {
if (inboxes === undefined) {
throw new Error(
`Unable to post on topic:"${topic}" at address:"${addr}". Subscriber doesn't exist.`

View file

@ -1,230 +0,0 @@
/* eslint-disable max-classes-per-file */
export function bytesToSize(bytes) {
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
if (bytes === 0) return 'n/a';
const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)), 10);
if (i === 0) return `${bytes} ${sizes[i]}`;
return `${(bytes / (1024 ** i)).toFixed(1)} ${sizes[i]}`;
}
export function diffMinutes(dt2, dt1) {
let diff = (dt2.getTime() - dt1.getTime()) / 1000;
diff /= 60;
return Math.abs(Math.round(diff));
}
export function isInSameDay(dt2, dt1) {
return (
dt2.getFullYear() === dt1.getFullYear()
&& dt2.getMonth() === dt1.getMonth()
&& dt2.getDate() === dt1.getDate()
);
}
/**
* @param {Event} ev
* @param {string} [targetSelector] element selector for Element.matches([selector])
*/
export function getEventCords(ev, targetSelector) {
let boxInfo;
const path = ev.nativeEvent.composedPath();
const target = targetSelector
? path.find((element) => element.matches?.(targetSelector))
: null;
if (target) {
boxInfo = target.getBoundingClientRect();
} else {
boxInfo = ev.target.getBoundingClientRect();
}
return {
x: boxInfo.x,
y: boxInfo.y,
width: boxInfo.width,
height: boxInfo.height,
detail: ev.detail,
};
}
export function abbreviateNumber(number) {
if (number > 99) return '99+';
return number;
}
export class Debounce {
constructor() {
this.timeoutId = null;
}
/**
* @param {function} func - callback function
* @param {number} wait - wait in milliseconds to call func
* @returns {func} debounceCallback - to pass arguments to func callback
*/
_(func, wait) {
const that = this;
return function debounceCallback(...args) {
clearTimeout(that.timeoutId);
that.timeoutId = setTimeout(() => {
func.apply(this, args);
that.timeoutId = null;
}, wait);
};
}
}
export class Throttle {
constructor() {
this.timeoutId = null;
}
/**
* @param {function} func - callback function
* @param {number} wait - wait in milliseconds to call func
* @returns {function} throttleCallback - to pass arguments to func callback
*/
_(func, wait) {
const that = this;
return function throttleCallback(...args) {
if (that.timeoutId !== null) return;
that.timeoutId = setTimeout(() => {
func.apply(this, args);
that.timeoutId = null;
}, wait);
};
}
}
export function getUrlPrams(paramName) {
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
return urlParams.get(paramName);
}
export function getScrollInfo(target) {
const scroll = {};
scroll.top = Math.round(target.scrollTop);
scroll.height = Math.round(target.scrollHeight);
scroll.viewHeight = Math.round(target.offsetHeight);
scroll.isScrollable = scroll.height > scroll.viewHeight;
return scroll;
}
export function avatarInitials(text) {
return [...text][0];
}
export function cssVar(name) {
return getComputedStyle(document.body).getPropertyValue(name);
}
export function setFavicon(url) {
const favicon = document.querySelector('#favicon');
if (!favicon) return;
favicon.setAttribute('href', url);
}
export function copyToClipboard(text) {
if (navigator.clipboard) {
navigator.clipboard.writeText(text);
} else {
const host = document.body;
const copyInput = document.createElement('input');
copyInput.style.position = 'fixed';
copyInput.style.opacity = '0';
copyInput.value = text;
host.append(copyInput);
copyInput.select();
copyInput.setSelectionRange(0, 99999);
document.execCommand('Copy');
copyInput.remove();
}
}
export function suffixRename(name, validator) {
let suffix = 2;
let newName = name;
do {
newName = name + suffix;
suffix += 1;
} while (validator(newName));
return newName;
}
export function getImageDimension(file) {
return new Promise((resolve) => {
const img = new Image();
img.onload = async () => {
resolve({
w: img.width,
h: img.height,
});
URL.revokeObjectURL(img.src);
};
img.src = URL.createObjectURL(file);
});
}
export function scaleDownImage(imageFile, width, height) {
return new Promise((resolve) => {
const imgURL = URL.createObjectURL(imageFile);
const img = new Image();
img.onload = () => {
let newWidth = img.width;
let newHeight = img.height;
if (newHeight <= height && newWidth <= width) {
resolve(imageFile);
}
if (newHeight > height) {
newWidth = Math.floor(newWidth * (height / newHeight));
newHeight = height;
}
if (newWidth > width) {
newHeight = Math.floor(newHeight * (width / newWidth));
newWidth = width;
}
const canvas = document.createElement('canvas');
canvas.width = newWidth;
canvas.height = newHeight;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, newWidth, newHeight);
canvas.toBlob((thumbnail) => {
URL.revokeObjectURL(imgURL);
resolve(thumbnail);
}, imageFile.type);
};
img.src = imgURL;
});
}
/**
* @param {sigil} string sigil to search for (for example '@', '#' or '$')
* @param {flags} string regex flags
* @param {prefix} string prefix appended at the beginning of the regex
* @returns {RegExp}
*/
export function idRegex(sigil, flags, prefix) {
const servername = '(?:[a-zA-Z0-9-.]*[a-zA-Z0-9]+|\\[\\S+?\\])(?::\\d+)?';
return new RegExp(`${prefix}(${sigil}\\S+:${servername})`, flags);
}
const matrixToRegex = /^https?:\/\/matrix.to\/#\/(\S+:\S+)/;
/**
* Parses a matrix.to URL into an matrix id.
* This function can later be extended to support matrix: URIs
* @param {string} uri The URI to parse
* @returns {string|null} The id or null if the URI does not match
*/
export function parseIdUri(uri) {
const res = decodeURIComponent(uri).match(matrixToRegex);
if (!res) return null;
return res[1];
}

View file

@ -54,6 +54,7 @@ export function abbreviateNumber(number: number) {
export class Debounce {
timeoutId: any;
constructor() {
this.timeoutId = null;
}
@ -63,7 +64,7 @@ export class Debounce {
* @param {number} wait - wait in milliseconds to call func
* @returns {func} debounceCallback - to pass arguments to func callback
*/
_(func: Function, wait: number) {
_(func: (...args) => void, wait: number) {
const debounceCallback = (...args) => {
clearTimeout(this.timeoutId);
this.timeoutId = setTimeout(() => {
@ -77,6 +78,7 @@ export class Debounce {
export class Throttle {
timeoutId: any;
constructor() {
this.timeoutId = null;
}
@ -86,7 +88,7 @@ export class Throttle {
* @param {number} wait - wait in milliseconds to call func
* @returns {function} throttleCallback - to pass arguments to func callback
*/
_(func: Function, wait: number) {
_(func: (...args) => void, wait: number) {
const throttleCallback = (...args) => {
if (this.timeoutId !== null) return;
this.timeoutId = setTimeout(() => {
@ -146,7 +148,7 @@ export function copyToClipboard(text: string) {
}
}
export function suffixRename(name: string | number, validator: Function) {
export function suffixRename(name: string, validator: (newName: string) => boolean) {
let suffix = 2;
let newName = name;
do {

View file

@ -5,45 +5,11 @@ const MAX_TAG_NESTING = 100;
let mx = null;
const permittedHtmlTags = [
'font',
'del',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'blockquote',
'p',
'a',
'ul',
'ol',
'sup',
'sub',
'li',
'b',
'i',
'u',
'strong',
'em',
'strike',
'code',
'hr',
'br',
'div',
'table',
'thead',
'tbody',
'tr',
'th',
'td',
'caption',
'pre',
'span',
'img',
'details',
'summary',
];
'font', 'del', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
'blockquote', 'p', 'a', 'ul', 'ol', 'sup', 'sub',
'li', 'b', 'i', 'u', 'strong', 'em', 'strike', 'code',
'hr', 'br', 'div', 'table', 'thead', 'tbody', 'tr', 'th',
'td', 'caption', 'pre', 'span', 'img', 'details', 'summary'];
const urlSchemes = ['https', 'http', 'ftp', 'mailto', 'magnet'];