forked from github/cinny
Remove unused javascript (#2470)
This commit is contained in:
@@ -1,135 +0,0 @@
|
||||
import EventEmitter from 'events';
|
||||
|
||||
class AsyncSearch extends EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this._reset();
|
||||
|
||||
this.RESULT_SENT = 'RESULT_SENT';
|
||||
}
|
||||
|
||||
_reset() {
|
||||
this.dataList = null;
|
||||
this.term = null;
|
||||
this.searchKeys = null;
|
||||
this.isContain = false;
|
||||
this.isCaseSensitive = false;
|
||||
this.normalizeUnicode = true;
|
||||
this.ignoreWhitespace = true;
|
||||
this.limit = null;
|
||||
this.findingList = [];
|
||||
|
||||
this.searchUptoIndex = 0;
|
||||
this.sessionStartTimestamp = 0;
|
||||
}
|
||||
|
||||
_softReset() {
|
||||
this.term = null;
|
||||
this.findingList = [];
|
||||
this.searchUptoIndex = 0;
|
||||
this.sessionStartTimestamp = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the search.
|
||||
* opts.keys are required when dataList items are object.
|
||||
*
|
||||
* @param {[string | object]} dataList - A list to search in
|
||||
* @param {object} opts - Options
|
||||
* @param {string | [string]} [opts.keys=null]
|
||||
* @param {boolean} [opts.isContain=false] - Add finding to result if it contain search term
|
||||
* @param {boolean} [opts.isCaseSensitive=false]
|
||||
* @param {boolean} [opts.normalizeUnicode=true]
|
||||
* @param {boolean} [opts.ignoreWhitespace=true]
|
||||
* @param {number} [opts.limit=null] - Stop search after limit
|
||||
*/
|
||||
setup(dataList, opts) {
|
||||
this._reset();
|
||||
this.dataList = dataList;
|
||||
this.searchKeys = opts?.keys || null;
|
||||
this.isContain = opts?.isContain || false;
|
||||
this.isCaseSensitive = opts?.isCaseSensitive || false;
|
||||
this.normalizeUnicode = opts?.normalizeUnicode || true;
|
||||
this.ignoreWhitespace = opts?.ignoreWhitespace || true;
|
||||
this.limit = opts?.limit || null;
|
||||
}
|
||||
|
||||
search(term) {
|
||||
this._softReset();
|
||||
|
||||
this.term = this._normalize(term);
|
||||
if (this.term === '') {
|
||||
this._sendFindings();
|
||||
return;
|
||||
}
|
||||
|
||||
this._find(this.sessionStartTimestamp, 0);
|
||||
}
|
||||
|
||||
_find(sessionTimestamp, lastFindingCount) {
|
||||
if (sessionTimestamp !== this.sessionStartTimestamp) return;
|
||||
this.sessionStartTimestamp = window.performance.now();
|
||||
|
||||
for (
|
||||
let searchIndex = this.searchUptoIndex;
|
||||
searchIndex < this.dataList.length;
|
||||
searchIndex += 1
|
||||
) {
|
||||
if (this._match(this.dataList[searchIndex])) {
|
||||
this.findingList.push(this.dataList[searchIndex]);
|
||||
if (typeof this.limit === 'number' && this.findingList.length >= this.limit) break;
|
||||
}
|
||||
|
||||
const calcFinishTime = window.performance.now();
|
||||
if (calcFinishTime - this.sessionStartTimestamp > 8) {
|
||||
const thisFindingCount = this.findingList.length;
|
||||
const thisSessionTimestamp = this.sessionStartTimestamp;
|
||||
if (lastFindingCount !== thisFindingCount) this._sendFindings();
|
||||
|
||||
this.searchUptoIndex = searchIndex + 1;
|
||||
setTimeout(() => this._find(thisSessionTimestamp, thisFindingCount));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (lastFindingCount !== this.findingList.length
|
||||
|| lastFindingCount === 0) this._sendFindings();
|
||||
this._softReset();
|
||||
}
|
||||
|
||||
_match(item) {
|
||||
if (typeof item === 'string') {
|
||||
return this._compare(item);
|
||||
}
|
||||
if (typeof item === 'object') {
|
||||
if (Array.isArray(this.searchKeys)) {
|
||||
return !!this.searchKeys.find((key) => this._compare(item[key]));
|
||||
}
|
||||
if (typeof this.searchKeys === 'string') {
|
||||
return this._compare(item[this.searchKeys]);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
_compare(item) {
|
||||
if (typeof item !== 'string') return false;
|
||||
const myItem = this._normalize(item);
|
||||
if (this.isContain) return myItem.indexOf(this.term) !== -1;
|
||||
return myItem.startsWith(this.term);
|
||||
}
|
||||
|
||||
_normalize(item) {
|
||||
let myItem = item.normalize(this.normalizeUnicode ? 'NFKC' : 'NFC');
|
||||
if (!this.isCaseSensitive) myItem = myItem.toLocaleLowerCase();
|
||||
if (this.ignoreWhitespace) myItem = myItem.replace(/\s/g, '');
|
||||
return myItem;
|
||||
}
|
||||
|
||||
_sendFindings() {
|
||||
this.emit(this.RESULT_SENT, this.findingList, this.term);
|
||||
}
|
||||
}
|
||||
|
||||
export default AsyncSearch;
|
||||
@@ -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];
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
import HashIC from '../../public/res/ic/outlined/hash.svg';
|
||||
import HashGlobeIC from '../../public/res/ic/outlined/hash-globe.svg';
|
||||
import HashLockIC from '../../public/res/ic/outlined/hash-lock.svg';
|
||||
import SpaceIC from '../../public/res/ic/outlined/space.svg';
|
||||
import SpaceGlobeIC from '../../public/res/ic/outlined/space-globe.svg';
|
||||
import SpaceLockIC from '../../public/res/ic/outlined/space-lock.svg';
|
||||
|
||||
const WELL_KNOWN_URI = '/.well-known/matrix/client';
|
||||
|
||||
export async function getBaseUrl(servername) {
|
||||
let protocol = 'https://';
|
||||
if (servername.match(/^https?:\/\//) !== null) protocol = '';
|
||||
const serverDiscoveryUrl = `${protocol}${servername}${WELL_KNOWN_URI}`;
|
||||
try {
|
||||
const result = await (await fetch(serverDiscoveryUrl, { method: 'GET' })).json();
|
||||
|
||||
const baseUrl = result?.['m.homeserver']?.base_url;
|
||||
if (baseUrl === undefined) throw new Error();
|
||||
return baseUrl;
|
||||
} catch (e) {
|
||||
return `${protocol}${servername}`;
|
||||
}
|
||||
}
|
||||
|
||||
export function getUsername(mx, userId) {
|
||||
const user = mx.getUser(userId);
|
||||
if (user === null) return userId;
|
||||
let username = user.displayName;
|
||||
if (typeof username === 'undefined') {
|
||||
username = userId;
|
||||
}
|
||||
return username;
|
||||
}
|
||||
|
||||
export function getUsernameOfRoomMember(roomMember) {
|
||||
return roomMember.name || roomMember.userId;
|
||||
}
|
||||
|
||||
export async function isRoomAliasAvailable(mx, alias) {
|
||||
try {
|
||||
const result = await mx.getRoomIdForAlias(alias);
|
||||
if (result.room_id) return false;
|
||||
return false;
|
||||
} catch (e) {
|
||||
if (e.errcode === 'M_NOT_FOUND') return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function getPowerLabel(powerLevel) {
|
||||
if (powerLevel > 9000) return 'Goku';
|
||||
if (powerLevel > 100) return 'Founder';
|
||||
if (powerLevel === 100) return 'Admin';
|
||||
if (powerLevel >= 50) return 'Mod';
|
||||
return null;
|
||||
}
|
||||
|
||||
export function parseReply(rawBody) {
|
||||
if (rawBody?.indexOf('>') !== 0) return null;
|
||||
let body = rawBody.slice(rawBody.indexOf('<') + 1);
|
||||
const user = body.slice(0, body.indexOf('>'));
|
||||
|
||||
body = body.slice(body.indexOf('>') + 2);
|
||||
const replyBody = body.slice(0, body.indexOf('\n\n'));
|
||||
body = body.slice(body.indexOf('\n\n') + 2);
|
||||
|
||||
if (user === '') return null;
|
||||
|
||||
const isUserId = user.match(/^@.+:.+/);
|
||||
|
||||
return {
|
||||
userId: isUserId ? user : null,
|
||||
displayName: isUserId ? null : user,
|
||||
replyBody,
|
||||
body,
|
||||
};
|
||||
}
|
||||
|
||||
export function trimHTMLReply(html) {
|
||||
if (!html) return html;
|
||||
const suffix = '</mx-reply>';
|
||||
const i = html.indexOf(suffix);
|
||||
if (i < 0) {
|
||||
return html;
|
||||
}
|
||||
return html.slice(i + suffix.length);
|
||||
}
|
||||
|
||||
export function joinRuleToIconSrc(joinRule, isSpace) {
|
||||
return ({
|
||||
restricted: () => (isSpace ? SpaceIC : HashIC),
|
||||
knock: () => (isSpace ? SpaceLockIC : HashLockIC),
|
||||
invite: () => (isSpace ? SpaceLockIC : HashLockIC),
|
||||
public: () => (isSpace ? SpaceGlobeIC : HashGlobeIC),
|
||||
}[joinRule]?.() || null);
|
||||
}
|
||||
|
||||
export function getIdServer(userId) {
|
||||
const idParts = userId.split(':');
|
||||
return idParts[1];
|
||||
}
|
||||
|
||||
export async function hasDevices(mx, userId) {
|
||||
try {
|
||||
const usersDeviceMap = await mx.getCrypto()?.getUserDeviceInfo([userId, mx.getUserId()], true);
|
||||
|
||||
return Array.from(usersDeviceMap.values())
|
||||
.every((deviceIdToDevices) => deviceIdToDevices.size > 0);
|
||||
} catch (e) {
|
||||
console.error("Error determining if it's possible to encrypt to all users: ", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
export function memberByAtoZ(m1, m2) {
|
||||
const aName = m1.name;
|
||||
const bName = m2.name;
|
||||
|
||||
if (aName.toLowerCase() < bName.toLowerCase()) {
|
||||
return -1;
|
||||
}
|
||||
if (aName.toLowerCase() > bName.toLowerCase()) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
export function memberByPowerLevel(m1, m2) {
|
||||
const pl1 = m1.powerLevel;
|
||||
const pl2 = m2.powerLevel;
|
||||
|
||||
if (pl1 > pl2) return -1;
|
||||
if (pl1 < pl2) return 1;
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user