fix lint "no-param-reassign"

This commit is contained in:
Johann150 2022-08-10 16:36:54 +02:00
parent 4f9ba4b8a8
commit 7a80015225
Signed by untrusted user: Johann150
GPG key ID: 9EE6577A2A06F8F1
28 changed files with 110 additions and 113 deletions

View file

@ -8,10 +8,10 @@ const urlRegex = /^https?:\/\/[\w\/:%#@$&?!()\[\]~.,=+\-]+/;
const urlRegexFull = /^https?:\/\/[\w\/:%#@$&?!()\[\]~.,=+\-]+$/; const urlRegexFull = /^https?:\/\/[\w\/:%#@$&?!()\[\]~.,=+\-]+$/;
export function fromHtml(html: string, hashtagNames?: string[]): string { export function fromHtml(html: string, hashtagNames?: string[]): string {
const dom = parse5.parseFragment(
// some AP servers like Pixelfed use br tags as well as newlines // some AP servers like Pixelfed use br tags as well as newlines
html = html.replace(/<br\s?\/?>\r?\n/gi, '\n'); html.replace(/<br\s?\/?>\r?\n/gi, '\n')
);
const dom = parse5.parseFragment(html);
let text = ''; let text = '';

View file

@ -4,8 +4,11 @@ export type Acct = {
}; };
export function parse(acct: string): Acct { export function parse(acct: string): Acct {
if (acct.startsWith('@')) acct = acct.substr(1); const split = acct.split('@');
const split = acct.split('@', 2); if (split[0].length == 0) {
// there was an initial at
split.shift();
}
return { username: split[0], host: split[1] || null }; return { username: split[0], host: split[1] || null };
} }

View file

@ -2,11 +2,11 @@ import { URL } from 'node:url';
import { toASCII } from 'punycode'; import { toASCII } from 'punycode';
import config from '@/config/index.js'; import config from '@/config/index.js';
export function getFullApAccount(username: string, host: string | null) { export function getFullApAccount(username: string, host: string | null): string {
return host ? `${username}@${toPuny(host)}` : `${username}@${toPuny(config.host)}`; return host ? `${username}@${toPuny(host)}` : `${username}@${toPuny(config.host)}`;
} }
export function isSelfHost(host: string) { export function isSelfHost(host: string | null): boolean {
if (host == null) return true; if (host == null) return true;
return toPuny(config.host) === toPuny(host); return toPuny(config.host) === toPuny(host);
} }

View file

@ -7,10 +7,8 @@ import * as crypto from 'node:crypto';
const TIME2000 = 946684800000; const TIME2000 = 946684800000;
let counter = crypto.randomBytes(2).readUInt16LE(0); let counter = crypto.randomBytes(2).readUInt16LE(0);
export function genId(date?: Date): string { export function genId(date?: Date = new Date()): string {
if (!date || (date > new Date())) date = new Date(); let t = Math.min(date, new Date());
let t = date.getTime();
t -= TIME2000; t -= TIME2000;
if (t < 0) t = 0; if (t < 0) t = 0;
if (isNaN(t)) throw new Error('Failed to create AID: Invalid Date'); if (isNaN(t)) throw new Error('Failed to create AID: Invalid Date');

View file

@ -54,10 +54,10 @@ export function convertLegacyReactions(reactions: Record<string, number>) {
return _reactions2; return _reactions2;
} }
export async function toDbReaction(reaction?: string | null, reacterHost?: string | null): Promise<string> { export async function toDbReaction(reaction?: string | null, idnReacterHost?: string | null): Promise<string> {
if (reaction == null) return await getFallbackReaction(); if (reaction == null) return await getFallbackReaction();
reacterHost = toPunyNullable(reacterHost); const reacterHost = toPunyNullable(idnReacterHost);
// 文字列タイプのリアクションを絵文字に変換 // 文字列タイプのリアクションを絵文字に変換
if (Object.keys(legacies).includes(reaction)) return legacies[reaction]; if (Object.keys(legacies).includes(reaction)) return legacies[reaction];
@ -124,8 +124,8 @@ export function decodeReaction(str: string): DecodedReaction {
}; };
} }
export function convertLegacyReaction(reaction: string): string { export function convertLegacyReaction(_reaction: string): string {
reaction = decodeReaction(reaction).reaction; const reaction = decodeReaction(_reaction).reaction;
if (Object.keys(legacies).includes(reaction)) return legacies[reaction]; if (Object.keys(legacies).includes(reaction)) return legacies[reaction];
return reaction; return reaction;
} }

View file

@ -52,12 +52,10 @@ export const FollowingRepository = db.getRepository(Following).extend({
opts?: { opts?: {
populateFollowee?: boolean; populateFollowee?: boolean;
populateFollower?: boolean; populateFollower?: boolean;
} } = {},
): Promise<Packed<'Following'>> { ): Promise<Packed<'Following'>> {
const following = typeof src === 'object' ? src : await this.findOneByOrFail({ id: src }); const following = typeof src === 'object' ? src : await this.findOneByOrFail({ id: src });
if (opts == null) opts = {};
return await awaitAll({ return await awaitAll({
id: following.id, id: following.id,
createdAt: following.createdAt.toISOString(), createdAt: following.createdAt.toISOString(),

View file

@ -65,9 +65,7 @@ export async function fetchNote(object: string | IObject): Promise<Note | null>
/** /**
* Noteを作成します * Noteを作成します
*/ */
export async function createNote(value: string | IObject, resolver?: Resolver, silent = false): Promise<Note | null> { export async function createNote(value: string | IObject, resolver?: Resolver = new Resolver(), silent = false): Promise<Note | null> {
if (resolver == null) resolver = new Resolver();
const object: any = await resolver.resolve(value); const object: any = await resolver.resolve(value);
const entryUri = getApId(value); const entryUri = getApId(value);
@ -302,8 +300,8 @@ export async function resolveNote(value: string | IObject, resolver?: Resolver):
} }
} }
export async function extractEmojis(tags: IObject | IObject[], host: string): Promise<Emoji[]> { export async function extractEmojis(tags: IObject | IObject[], idnHost: string): Promise<Emoji[]> {
host = toPuny(host); const host = toPuny(idnHost);
if (!tags) return []; if (!tags) return [];

View file

@ -134,15 +134,13 @@ export async function fetchPerson(uri: string, resolver?: Resolver): Promise<Cac
/** /**
* Personを作成します * Personを作成します
*/ */
export async function createPerson(uri: string, resolver?: Resolver): Promise<User> { export async function createPerson(uri: string, resolver?: Resolver = new Resolver()): Promise<User> {
if (typeof uri !== 'string') throw new Error('uri is not string'); if (typeof uri !== 'string') throw new Error('uri is not string');
if (uri.startsWith(config.url)) { if (uri.startsWith(config.url)) {
throw new StatusError('cannot resolve local user', 400, 'cannot resolve local user'); throw new StatusError('cannot resolve local user', 400, 'cannot resolve local user');
} }
if (resolver == null) resolver = new Resolver();
const object = await resolver.resolve(uri) as any; const object = await resolver.resolve(uri) as any;
const person = validateActor(object, uri); const person = validateActor(object, uri);
@ -283,7 +281,7 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us
* @param resolver Resolver * @param resolver Resolver
* @param hint Hint of Person object (Personの場合Remote resolveをせずに更新に利用します) * @param hint Hint of Person object (Personの場合Remote resolveをせずに更新に利用します)
*/ */
export async function updatePerson(uri: string, resolver?: Resolver | null, hint?: IObject): Promise<void> { export async function updatePerson(uri: string, resolver?: Resolver = new Resolver(), hint?: IObject): Promise<void> {
if (typeof uri !== 'string') throw new Error('uri is not string'); if (typeof uri !== 'string') throw new Error('uri is not string');
// URIがこのサーバーを指しているならスキップ // URIがこのサーバーを指しているならスキップ
@ -299,8 +297,6 @@ export async function updatePerson(uri: string, resolver?: Resolver | null, hint
} }
//#endregion //#endregion
if (resolver == null) resolver = new Resolver();
const object = hint || await resolver.resolve(uri); const object = hint || await resolver.resolve(uri);
const person = validateActor(object, uri); const person = validateActor(object, uri);
@ -405,8 +401,7 @@ export async function resolvePerson(uri: string, resolver?: Resolver): Promise<C
//#endregion //#endregion
// リモートサーバーからフェッチしてきて登録 // リモートサーバーからフェッチしてきて登録
if (resolver == null) resolver = new Resolver(); return await createPerson(uri, resolver ?? new Resolver());
return await createPerson(uri, resolver);
} }
const services: { const services: {
@ -419,10 +414,11 @@ const services: {
const $discord = (id: string, name: string) => { const $discord = (id: string, name: string) => {
if (typeof name !== 'string') { if (typeof name !== 'string') {
name = 'unknown#0000'; return { id, username: 'unknown', discriminator: '0000' };
} } else {
const [username, discriminator] = name.split('#'); const [username, discriminator] = name.split('#');
return { id, username, discriminator }; return { id, username, discriminator };
}
}; };
function addService(target: { [x: string]: any }, source: IApPropertyValue) { function addService(target: { [x: string]: any }, source: IApPropertyValue) {

View file

@ -5,9 +5,7 @@ import Resolver from '../resolver.js';
import { IObject, IQuestion, isQuestion } from '../type.js'; import { IObject, IQuestion, isQuestion } from '../type.js';
import { apLogger } from '../logger.js'; import { apLogger } from '../logger.js';
export async function extractPollFromQuestion(source: string | IObject, resolver?: Resolver): Promise<IPoll> { export async function extractPollFromQuestion(source: string | IObject, resolver?: Resolver = new Resolver()): Promise<IPoll> {
if (resolver == null) resolver = new Resolver();
const question = await resolver.resolve(source); const question = await resolver.resolve(source);
if (!isQuestion(question)) { if (!isQuestion(question)) {

View file

@ -53,7 +53,5 @@ export const attachLdSignature = async (activity: any, user: { id: User['id']; h
const ldSignature = new LdSignature(); const ldSignature = new LdSignature();
ldSignature.debug = false; ldSignature.debug = false;
activity = await ldSignature.signRsaSignature2017(activity, keypair.privateKey, `${config.url}/users/${user.id}#main-key`); return await ldSignature.signRsaSignature2017(activity, keypair.privateKey, `${config.url}/users/${user.id}#main-key`);
return activity;
}; };

View file

@ -2,7 +2,7 @@ import { URL } from 'node:url';
import chalk from 'chalk'; import chalk from 'chalk';
import { IsNull } from 'typeorm'; import { IsNull } from 'typeorm';
import config from '@/config/index.js'; import config from '@/config/index.js';
import { toPuny } from '@/misc/convert-host.js'; import { isSelfHost, toPuny } from '@/misc/convert-host.js';
import { User, IRemoteUser } from '@/models/entities/user.js'; import { User, IRemoteUser } from '@/models/entities/user.js';
import { Users } from '@/models/index.js'; import { Users } from '@/models/index.js';
import webFinger from './webfinger.js'; import webFinger from './webfinger.js';
@ -11,7 +11,7 @@ import { remoteLogger } from './logger.js';
const logger = remoteLogger.createSubLogger('resolve-user'); const logger = remoteLogger.createSubLogger('resolve-user');
export async function resolveUser(username: string, host: string | null): Promise<User> { export async function resolveUser(username: string, idnHost: string | null): Promise<User> {
const usernameLower = username.toLowerCase(); const usernameLower = username.toLowerCase();
if (host == null) { if (host == null) {
@ -25,9 +25,7 @@ export async function resolveUser(username: string, host: string | null): Promis
}); });
} }
host = toPuny(host); if (isSelfHost(idnHost)) {
if (config.host === host) {
logger.info(`return local user: ${usernameLower}`); logger.info(`return local user: ${usernameLower}`);
return await Users.findOneBy({ usernameLower, host: IsNull() }).then(u => { return await Users.findOneBy({ usernameLower, host: IsNull() }).then(u => {
if (u == null) { if (u == null) {
@ -38,6 +36,8 @@ export async function resolveUser(username: string, host: string | null): Promis
}); });
} }
// `idnHost` can not be null here because that would have branched off with `isSelfHost`.
const host = toPuny(idnHost!);
const user = await Users.findOneBy({ usernameLower, host }) as IRemoteUser | null; const user = await Users.findOneBy({ usernameLower, host }) as IRemoteUser | null;
const acctLower = `${usernameLower}@${host}`; const acctLower = `${usernameLower}@${host}`;

View file

@ -135,8 +135,9 @@ export async function readGroupMessagingMessage(
} }
export async function deliverReadActivity(user: { id: User['id']; host: null; }, recipient: IRemoteUser, messages: MessagingMessage | MessagingMessage[]) { export async function deliverReadActivity(user: { id: User['id']; host: null; }, recipient: IRemoteUser, messages: MessagingMessage | MessagingMessage[]) {
messages = toArray(messages).filter(x => x.uri); const contents = toArray(messages)
const contents = messages.map(x => renderReadActivity(user, x)); .filter(x => x.uri)
.map(x => renderReadActivity(user, x));
if (contents.length > 1) { if (contents.length > 1) {
const collection = orderedCollection(null, contents.length, undefined, undefined, contents); const collection = orderedCollection(null, contents.length, undefined, undefined, contents);

View file

@ -8,21 +8,22 @@ export class ApiError extends Error {
public httpStatusCode?: number; public httpStatusCode?: number;
public info?: any; public info?: any;
constructor(e?: E | null | undefined, info?: any | null | undefined) { constructor(
if (e == null) e = { e?: E | null | undefined = {
message: 'Internal error occurred. Please contact us if the error persists.', message: 'Internal error occurred. Please contact us if the error persists.',
code: 'INTERNAL_ERROR', code: 'INTERNAL_ERROR',
id: '5d37dbcb-891e-41ca-a3d6-e690c97775ac', id: '5d37dbcb-891e-41ca-a3d6-e690c97775ac',
kind: 'server', kind: 'server',
httpStatusCode: 500, httpStatusCode: 500,
}; },
info?: any | null | undefined
) {
super(e.message); super(e.message);
this.message = e.message; this.message = e.message;
this.code = e.code; this.code = e.code;
this.id = e.id; this.id = e.id;
this.kind = e.kind || 'client'; this.kind = e.kind ?? 'client';
this.httpStatusCode = e.httpStatusCode; this.httpStatusCode = e.httpStatusCode ?? 500;
this.info = info; this.info = info;
} }
} }

View file

@ -256,9 +256,12 @@ export async function generateAlts(path: string, type: string, generateWeb: bool
/** /**
* Upload to ObjectStorage * Upload to ObjectStorage
*/ */
async function upload(key: string, stream: fs.ReadStream | Buffer, type: string, filename?: string) { async function upload(key: string, stream: fs.ReadStream | Buffer, _type: string, filename?: string) {
if (type === 'image/apng') type = 'image/png'; const type = (_type === 'image/apng')
if (!FILE_TYPE_BROWSERSAFE.includes(type)) type = 'application/octet-stream'; ? 'image/png'
: (FILE_TYPE_BROWSERSAFE.includes(_type))
? _type
: 'application/octet-stream';
const meta = await fetchMeta(); const meta = await fetchMeta();

View file

@ -36,12 +36,6 @@ export async function uploadFromUrl({
name = null; name = null;
} }
// If the comment is same as the name, skip comment
// (image.name is passed in when receiving attachment)
if (comment !== null && name === comment) {
comment = null;
}
// Create temp file // Create temp file
const [path, cleanup] = await createTemp(); const [path, cleanup] = await createTemp();
@ -49,7 +43,20 @@ export async function uploadFromUrl({
// write content at URL to temp file // write content at URL to temp file
await downloadUrl(url, path); await downloadUrl(url, path);
const driveFile = await addFile({ user, path, name, comment, folderId, force, isLink, url, uri, sensitive }); const driveFile = await addFile({
user,
path,
name,
// If the comment is same as the name, skip comment
// (image.name is passed in when receiving attachment)
comment: name === comment ? null : comment,
folderId,
force,
isLink,
url,
uri,
sensitive,
});
logger.succ(`Got: ${driveFile.id}`); logger.succ(`Got: ${driveFile.id}`);
return driveFile!; return driveFile!;
} catch (e) { } catch (e) {

View file

@ -47,10 +47,9 @@ export default class Logger {
return logger; return logger;
} }
private log(level: Level, message: string, data?: Record<string, any> | null, important = false, subDomains: Domain[] = [], store = true): void { private log(level: Level, message: string, data?: Record<string, any> | null, important = false, subDomains: Domain[] = [], _store = true): void {
if (envOption.quiet) return; if (envOption.quiet) return;
if (!this.store) store = false; const store = _store && this.store && (level !== 'debug');
if (level === 'debug') store = false;
if (this.parentLogger) { if (this.parentLogger) {
this.parentLogger.log(level, message, data, important, [this.domain].concat(subDomains), store); this.parentLogger.log(level, message, data, important, [this.domain].concat(subDomains), store);
@ -95,9 +94,8 @@ export default class Logger {
} }
} }
public error(x: string | Error, data?: Record<string, any> | null, important = false): void { // 実行を継続できない状況で使う public error(x: string | Error, data?: Record<string, any> = {}, important = false): void { // 実行を継続できない状況で使う
if (x instanceof Error) { if (x instanceof Error) {
data = data || {};
data.e = x; data.e = x;
this.log('error', x.toString(), data, important); this.log('error', x.toString(), data, important);
} else if (typeof x === 'object') { } else if (typeof x === 'object') {

View file

@ -33,14 +33,14 @@ export default async (user: { id: User['id']; host: User['host']; }, note: Note,
} }
// TODO: cache // TODO: cache
reaction = await toDbReaction(reaction, user.host); const dbReaction = await toDbReaction(reaction, user.host);
const record: NoteReaction = { const record: NoteReaction = {
id: genId(), id: genId(),
createdAt: new Date(), createdAt: new Date(),
noteId: note.id, noteId: note.id,
userId: user.id, userId: user.id,
reaction, reaction: dbReaction,
}; };
// Create reaction // Create reaction
@ -53,7 +53,7 @@ export default async (user: { id: User['id']; host: User['host']; }, note: Note,
userId: user.id, userId: user.id,
}); });
if (exists.reaction !== reaction) { if (exists.reaction !== dbReaction) {
// 別のリアクションがすでにされていたら置き換える // 別のリアクションがすでにされていたら置き換える
await deleteReaction(user, note); await deleteReaction(user, note);
await NoteReactions.insert(record); await NoteReactions.insert(record);
@ -67,7 +67,7 @@ export default async (user: { id: User['id']; host: User['host']; }, note: Note,
} }
// Increment reactions count // Increment reactions count
const sql = `jsonb_set("reactions", '{${reaction}}', (COALESCE("reactions"->>'${reaction}', '0')::int + 1)::text::jsonb)`; const sql = `jsonb_set("reactions", '{${dbReaction}}', (COALESCE("reactions"->>'${dbReaction}', '0')::int + 1)::text::jsonb)`;
await Notes.createQueryBuilder().update() await Notes.createQueryBuilder().update()
.set({ .set({
reactions: () => sql, reactions: () => sql,
@ -79,7 +79,7 @@ export default async (user: { id: User['id']; host: User['host']; }, note: Note,
perUserReactionsChart.update(user, note); perUserReactionsChart.update(user, note);
// カスタム絵文字リアクションだったら絵文字情報も送る // カスタム絵文字リアクションだったら絵文字情報も送る
const decodedReaction = decodeReaction(reaction); const decodedReaction = decodeReaction(dbReaction);
const emoji = await Emojis.findOne({ const emoji = await Emojis.findOne({
where: { where: {
@ -103,7 +103,7 @@ export default async (user: { id: User['id']; host: User['host']; }, note: Note,
createNotification(note.userId, 'reaction', { createNotification(note.userId, 'reaction', {
notifierId: user.id, notifierId: user.id,
noteId: note.id, noteId: note.id,
reaction, reaction: dbReaction,
}); });
} }
@ -116,7 +116,7 @@ export default async (user: { id: User['id']; host: User['host']; }, note: Note,
createNotification(watcher.userId, 'reaction', { createNotification(watcher.userId, 'reaction', {
notifierId: user.id, notifierId: user.id,
noteId: note.id, noteId: note.id,
reaction, reaction: dbReaction,
}); });
} }
}); });

View file

@ -6,8 +6,8 @@ import { Cache } from '@/misc/cache.js';
const cache = new Cache<Instance>(1000 * 60 * 60); const cache = new Cache<Instance>(1000 * 60 * 60);
export async function registerOrFetchInstanceDoc(host: string): Promise<Instance> { export async function registerOrFetchInstanceDoc(idnHost: string): Promise<Instance> {
host = toPuny(host); const host = toPuny(idnHost);
const cached = cache.get(host); const cached = cache.get(host);
if (cached) return cached; if (cached) return cached;

View file

@ -21,8 +21,8 @@ export async function updateUsertags(user: User, tags: string[]) {
} }
} }
export async function updateHashtag(user: { id: User['id']; host: User['host']; }, tag: string, isUserAttached = false, inc = true) { export async function updateHashtag(user: { id: User['id']; host: User['host']; }, _tag: string, isUserAttached = false, inc = true) {
tag = normalizeForSearch(tag); const tag = normalizeForSearch(_tag);
const index = await Hashtags.findOneBy({ name: tag }); const index = await Hashtags.findOneBy({ name: tag });

View file

@ -400,18 +400,18 @@ function chooseFolder(folderToChoose: Misskey.entities.DriveFolder) {
} }
} }
function move(target?: Misskey.entities.DriveFolder) { function move(target?: string | Misskey.entities.DriveFolder) {
if (!target) { if (!target) {
goRoot(); goRoot();
return; return;
} else if (typeof target === 'object') {
target = target.id;
} }
const targetId = typeof target === 'string' ? target : target.id;
fetching.value = true; fetching.value = true;
os.api('drive/folders/show', { os.api('drive/folders/show', {
folderId: target folderId: targetId,
}).then(folderToMove => { }).then(folderToMove => {
folder.value = folderToMove; folder.value = folderToMove;
hierarchyFolders.value = []; hierarchyFolders.value = [];

View file

@ -308,8 +308,7 @@ function paste(event: ClipboardEvent) {
} }
} }
function done(query?: any): boolean | void { function done(query?: any = q.value): boolean | void {
if (query == null) query = q.value;
if (query == null || typeof query !== 'string') return; if (query == null || typeof query !== 'string') return;
const q2 = query.replace(/:/g, ''); const q2 = query.replace(/:/g, '');

View file

@ -332,14 +332,12 @@ export default defineComponent({
// //
applyTransformHeight(height) { applyTransformHeight(height) {
if (height > window.innerHeight) height = window.innerHeight; (this.$el as any).style.height = Math.min(height, window.innerHeight) + 'px';
(this.$el as any).style.height = height + 'px';
}, },
// //
applyTransformWidth(width) { applyTransformWidth(width) {
if (width > window.innerWidth) width = window.innerWidth; (this.$el as any).style.width = Math.min(width, window.innerWidth) + 'px';
(this.$el as any).style.width = width + 'px';
}, },
// Y // Y

View file

@ -1,9 +1,8 @@
export default (v, digits = 0) => { export default (v: null | number, digits = 0) => {
if (v == null) return '?'; if (v == null) return '?';
const sizes = ['B', 'KB', 'MB', 'GB', 'TB']; const sizes = ['B', 'KiB', 'MiB', 'GiB', 'TiB'];
if (v === 0) return '0'; if (v === 0) return '0';
const isMinus = v < 0;
if (isMinus) v = -v; const i = Math.floor(Math.log(Math.abs(v)) / Math.log(1024));
const i = Math.floor(Math.log(v) / Math.log(1024)); return (v < 0 ? '-' : '') + (Math.abs(v) / Math.pow(1024, i)).toFixed(digits).replace(/\.0+$/, '') + sizes[i];
return (isMinus ? '-' : '') + (v / Math.pow(1024, i)).toFixed(digits).replace(/\.0+$/, '') + sizes[i];
}; };

View file

@ -25,9 +25,7 @@ type ParsedPath = (string | {
function parsePath(path: string): ParsedPath { function parsePath(path: string): ParsedPath {
const res = [] as ParsedPath; const res = [] as ParsedPath;
path = path.substring(1); for (const part of path.substring(1).split('/')) {
for (const part of path.split('/')) {
if (part.includes(':')) { if (part.includes(':')) {
const prefix = part.substring(0, part.indexOf(':')); const prefix = part.substring(0, part.indexOf(':'));
const placeholder = part.substring(part.indexOf(':') + 1); const placeholder = part.substring(part.indexOf(':') + 1);
@ -81,9 +79,10 @@ export class Router extends EventEmitter<{
this.navigate(currentPath, null, true); this.navigate(currentPath, null, true);
} }
public resolve(path: string): { route: RouteDef; props: Map<string, string>; } | null { public resolve(_path: string): { route: RouteDef; props: Map<string, string>; } | null {
let queryString: string | null = null; let queryString: string | null = null;
let hash: string | null = null; let hash: string | null = null;
let path: string = _path;
if (path[0] === '/') path = path.substring(1); if (path[0] === '/') path = path.substring(1);
if (path.includes('#')) { if (path.includes('#')) {
hash = path.substring(path.indexOf('#') + 1); hash = path.substring(path.indexOf('#') + 1);
@ -180,11 +179,11 @@ export class Router extends EventEmitter<{
} }
const isSamePath = beforePath === path; const isSamePath = beforePath === path;
if (isSamePath && key == null) key = this.currentKey;
this.currentComponent = res.route.component; this.currentComponent = res.route.component;
this.currentProps = res.props; this.currentProps = res.props;
this.currentRoute.value = res.route; this.currentRoute.value = res.route;
this.currentKey = this.currentRoute.value.globalCacheKey ?? key ?? Date.now().toString(); this.currentKey = this.currentRoute.value.globalCacheKey ?? key ?? (isSamePath ? this.currentKey : null) ?? Date.now().toString();
if (!initial) { if (!initial) {
this.emit('change', { this.emit('change', {

View file

@ -209,8 +209,8 @@ function onMessage(message) {
function onRead(x) { function onRead(x) {
if (user) { if (user) {
if (!Array.isArray(x)) x = [x]; // ensure x is an array or turn it into one
for (const id of x) { for (const id of [x].flat()) {
if (pagingComponent.items.some(y => y.id === id)) { if (pagingComponent.items.some(y => y.id === id)) {
const exist = pagingComponent.items.map(y => y.id).indexOf(id); const exist = pagingComponent.items.map(y => y.id).indexOf(id);
pagingComponent.items[exist] = { pagingComponent.items[exist] = {

View file

@ -1,6 +1,7 @@
export function focusPrev(el: Element | null, self = false, scroll = true) { export function focusPrev(_el: Element | null, self = false, scroll = true) {
if (el == null) return; if (_el == null) return;
if (!self) el = el.previousElementSibling; const el = self ? _el : _el.previousElementSibling;
if (el) { if (el) {
if (el.hasAttribute('tabindex')) { if (el.hasAttribute('tabindex')) {
(el as HTMLElement).focus({ (el as HTMLElement).focus({
@ -12,9 +13,10 @@ export function focusPrev(el: Element | null, self = false, scroll = true) {
} }
} }
export function focusNext(el: Element | null, self = false, scroll = true) { export function focusNext(_el: Element | null, self = false, scroll = true) {
if (el == null) return; if (_el == null) return;
if (!self) el = el.nextElementSibling; const el = self ? _el : _el.nextElementSibling;
if (el) { if (el) {
if (el.hasAttribute('tabindex')) { if (el.hasAttribute('tabindex')) {
(el as HTMLElement).focus({ (el as HTMLElement).focus({

View file

@ -17,7 +17,8 @@ type Action = {
allowRepeat: boolean; allowRepeat: boolean;
}; };
const parseKeymap = (keymap: Keymap) => Object.entries(keymap).map(([patterns, callback]): Action => { const parseKeymap = (keymap: Keymap) => Object.entries(keymap).map(([_patterns, callback]): Action => {
let patterns = _patterns;
const result = { const result = {
patterns: [], patterns: [],
callback, callback,

View file

@ -33,7 +33,7 @@ export function uploadFile(
name?: string, name?: string,
keepOriginal: boolean = defaultStore.state.keepOriginalUploading keepOriginal: boolean = defaultStore.state.keepOriginalUploading
): Promise<Misskey.entities.DriveFile> { ): Promise<Misskey.entities.DriveFile> {
if (folder && typeof folder === 'object') folder = folder.id; const folderId = typeof folder === 'string' ? folder : folder.id;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const id = Math.random().toString(); const id = Math.random().toString();
@ -73,7 +73,7 @@ export function uploadFile(
formData.append('force', 'true'); formData.append('force', 'true');
formData.append('file', resizedImage || file); formData.append('file', resizedImage || file);
formData.append('name', ctx.name); formData.append('name', ctx.name);
if (folder) formData.append('folderId', folder); if (folderId) formData.append('folderId', folderId);
const xhr = new XMLHttpRequest(); const xhr = new XMLHttpRequest();
xhr.open('POST', apiUrl + '/drive/files/create', true); xhr.open('POST', apiUrl + '/drive/files/create', true);