Apply new eslint rules; default to prettier for styling
This commit is contained in:
parent
f22cce8881
commit
dc84af9937
218 changed files with 3876 additions and 3564 deletions
|
@ -22,11 +22,11 @@ export class Websocket extends EventEmitter {
|
|||
private token = '';
|
||||
|
||||
// Connects to the websocket instance and sets the token for the initial request.
|
||||
connect (url: string): this {
|
||||
connect(url: string): this {
|
||||
this.url = url;
|
||||
|
||||
this.socket = new Sockette(`${this.url}`, {
|
||||
onmessage: e => {
|
||||
onmessage: (e) => {
|
||||
try {
|
||||
const { event, args } = JSON.parse(e.data);
|
||||
args ? this.emit(event, ...args) : this.emit(event);
|
||||
|
@ -47,11 +47,11 @@ export class Websocket extends EventEmitter {
|
|||
this.authenticate();
|
||||
},
|
||||
onclose: () => this.emit('SOCKET_CLOSE'),
|
||||
onerror: error => this.emit('SOCKET_ERROR', error),
|
||||
onerror: (error) => this.emit('SOCKET_ERROR', error),
|
||||
});
|
||||
|
||||
this.timer = setTimeout(() => {
|
||||
this.backoff = (this.backoff + 2500 >= 20000) ? 20000 : this.backoff + 2500;
|
||||
this.backoff = this.backoff + 2500 >= 20000 ? 20000 : this.backoff + 2500;
|
||||
this.socket && this.socket.close();
|
||||
clearTimeout(this.timer);
|
||||
|
||||
|
@ -64,7 +64,7 @@ export class Websocket extends EventEmitter {
|
|||
|
||||
// Sets the authentication token to use when sending commands back and forth
|
||||
// between the websocket instance.
|
||||
setToken (token: string, isUpdate = false): this {
|
||||
setToken(token: string, isUpdate = false): this {
|
||||
this.token = token;
|
||||
|
||||
if (isUpdate) {
|
||||
|
@ -74,30 +74,33 @@ export class Websocket extends EventEmitter {
|
|||
return this;
|
||||
}
|
||||
|
||||
authenticate () {
|
||||
authenticate() {
|
||||
if (this.url && this.token) {
|
||||
this.send('auth', this.token);
|
||||
}
|
||||
}
|
||||
|
||||
close (code?: number, reason?: string) {
|
||||
close(code?: number, reason?: string) {
|
||||
this.url = null;
|
||||
this.token = '';
|
||||
this.socket && this.socket.close(code, reason);
|
||||
}
|
||||
|
||||
open () {
|
||||
open() {
|
||||
this.socket && this.socket.open();
|
||||
}
|
||||
|
||||
reconnect () {
|
||||
reconnect() {
|
||||
this.socket && this.socket.reconnect();
|
||||
}
|
||||
|
||||
send (event: string, payload?: string | string[]) {
|
||||
this.socket && this.socket.send(JSON.stringify({
|
||||
event,
|
||||
args: Array.isArray(payload) ? payload : [ payload ],
|
||||
}));
|
||||
send(event: string, payload?: string | string[]) {
|
||||
this.socket &&
|
||||
this.socket.send(
|
||||
JSON.stringify({
|
||||
event,
|
||||
args: Array.isArray(payload) ? payload : [payload],
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ export class ScrollDownHelperAddon implements ITerminalAddon {
|
|||
private terminal: Terminal = new Terminal();
|
||||
private element?: HTMLDivElement;
|
||||
|
||||
activate (terminal: Terminal): void {
|
||||
activate(terminal: Terminal): void {
|
||||
this.terminal = terminal;
|
||||
|
||||
this.terminal.onScroll(() => {
|
||||
|
@ -22,11 +22,11 @@ export class ScrollDownHelperAddon implements ITerminalAddon {
|
|||
this.show();
|
||||
}
|
||||
|
||||
dispose (): void {
|
||||
dispose(): void {
|
||||
// ignore
|
||||
}
|
||||
|
||||
show (): void {
|
||||
show(): void {
|
||||
if (!this.terminal || !this.terminal.element) {
|
||||
return;
|
||||
}
|
||||
|
@ -38,7 +38,8 @@ export class ScrollDownHelperAddon implements ITerminalAddon {
|
|||
this.terminal.element.style.position = 'relative';
|
||||
|
||||
this.element = document.createElement('div');
|
||||
this.element.innerHTML = '<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="bell" class="svg-inline--fa fa-bell fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M224 512c35.32 0 63.97-28.65 63.97-64H160.03c0 35.35 28.65 64 63.97 64zm215.39-149.71c-19.32-20.76-55.47-51.99-55.47-154.29 0-77.7-54.48-139.9-127.94-155.16V32c0-17.67-14.32-32-31.98-32s-31.98 14.33-31.98 32v20.84C118.56 68.1 64.08 130.3 64.08 208c0 102.3-36.15 133.53-55.47 154.29-6 6.45-8.66 14.16-8.61 21.71.11 16.4 12.98 32 32.1 32h383.8c19.12 0 32-15.6 32.1-32 .05-7.55-2.61-15.27-8.61-21.71z"></path></svg>';
|
||||
this.element.innerHTML =
|
||||
'<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="bell" class="svg-inline--fa fa-bell fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M224 512c35.32 0 63.97-28.65 63.97-64H160.03c0 35.35 28.65 64 63.97 64zm215.39-149.71c-19.32-20.76-55.47-51.99-55.47-154.29 0-77.7-54.48-139.9-127.94-155.16V32c0-17.67-14.32-32-31.98-32s-31.98 14.33-31.98 32v20.84C118.56 68.1 64.08 130.3 64.08 208c0 102.3-36.15 133.53-55.47 154.29-6 6.45-8.66 14.16-8.61 21.71.11 16.4 12.98 32 32.1 32h383.8c19.12 0 32-15.6 32.1-32 .05-7.55-2.61-15.27-8.61-21.71z"></path></svg>';
|
||||
this.element.style.position = 'absolute';
|
||||
this.element.style.right = '1.5rem';
|
||||
this.element.style.bottom = '.5rem';
|
||||
|
@ -56,13 +57,13 @@ export class ScrollDownHelperAddon implements ITerminalAddon {
|
|||
this.terminal.element.appendChild(this.element);
|
||||
}
|
||||
|
||||
hide (): void {
|
||||
hide(): void {
|
||||
if (this.element) {
|
||||
this.element.style.visibility = 'hidden';
|
||||
}
|
||||
}
|
||||
|
||||
isScrolledDown (): boolean {
|
||||
isScrolledDown(): boolean {
|
||||
return this.terminal.buffer.active.viewportY === this.terminal.buffer.active.baseY;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { DependencyList, useMemo } from 'react';
|
||||
import { useDeepMemoize } from '@/plugins/useDeepMemoize';
|
||||
|
||||
export const useDeepCompareMemo = <T> (callback: () => T, dependencies: DependencyList) =>
|
||||
export const useDeepCompareMemo = <T>(callback: () => T, dependencies: DependencyList) =>
|
||||
useMemo(callback, useDeepMemoize(dependencies));
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { DependencyList, MutableRefObject, useRef } from 'react';
|
||||
import isEqual from 'react-fast-compare';
|
||||
|
||||
export const useDeepMemoize = <T = DependencyList> (value: T): T => {
|
||||
export const useDeepMemoize = <T = DependencyList>(value: T): T => {
|
||||
const ref: MutableRefObject<T | undefined> = useRef();
|
||||
|
||||
if (!isEqual(value, ref.current)) {
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
import { useEffect, useRef } from 'react';
|
||||
|
||||
export default (eventName: string, handler: (e: Event | CustomEvent | UIEvent | any) => void, options?: boolean | EventListenerOptions) => {
|
||||
export default (
|
||||
eventName: string,
|
||||
handler: (e: Event | CustomEvent | UIEvent | any) => void,
|
||||
options?: boolean | EventListenerOptions
|
||||
) => {
|
||||
const savedHandler = useRef<any>(null);
|
||||
|
||||
useEffect(() => {
|
||||
savedHandler.current = handler;
|
||||
}, [ handler ]);
|
||||
}, [handler]);
|
||||
|
||||
useEffect(() => {
|
||||
const isSupported = window && window.addEventListener;
|
||||
|
@ -16,5 +20,5 @@ export default (eventName: string, handler: (e: Event | CustomEvent | UIEvent |
|
|||
return () => {
|
||||
window.removeEventListener(eventName, eventListener);
|
||||
};
|
||||
}, [ eventName, window ]);
|
||||
}, [eventName, window]);
|
||||
};
|
||||
|
|
|
@ -6,8 +6,8 @@ import { ServerContext } from '@/state/server';
|
|||
export const getDirectorySwrKey = (uuid: string, directory: string): string => `${uuid}:files:${directory}`;
|
||||
|
||||
export default () => {
|
||||
const uuid = ServerContext.useStoreState(state => state.server.data!.uuid);
|
||||
const directory = ServerContext.useStoreState(state => state.files.directory);
|
||||
const uuid = ServerContext.useStoreState((state) => state.server.data!.uuid);
|
||||
const directory = ServerContext.useStoreState((state) => state.files.directory);
|
||||
|
||||
return useSWR<FileObject[]>(
|
||||
getDirectorySwrKey(uuid, directory),
|
||||
|
@ -17,6 +17,6 @@ export default () => {
|
|||
revalidateOnMount: false,
|
||||
refreshInterval: 0,
|
||||
errorRetryCount: 2,
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
|
|
|
@ -7,12 +7,12 @@ import { isEmptyObject, isObject } from '@/lib/objects';
|
|||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
export default <T extends {}>(data: T): T => {
|
||||
const empty = [ undefined, null, '' ] as unknown[];
|
||||
const empty = [undefined, null, ''] as unknown[];
|
||||
|
||||
const removeEmptyValues = (input: T): T =>
|
||||
Object.entries(input)
|
||||
.filter(([ _, value ]) => !empty.includes(value))
|
||||
.reduce((obj, [ k, v ]) => {
|
||||
.filter(([_, value]) => !empty.includes(value))
|
||||
.reduce((obj, [k, v]) => {
|
||||
const parsed = isObject(v) ? removeEmptyValues(v as any) : v;
|
||||
|
||||
return isObject(parsed) && isEmptyObject(parsed) ? obj : { ...obj, [k]: parsed };
|
||||
|
|
|
@ -9,7 +9,7 @@ export default () => {
|
|||
.substring(1)
|
||||
.split('&')
|
||||
.reduce((obj, str) => {
|
||||
const [ key, value = '' ] = str.split('=');
|
||||
const [key, value = ''] = str.split('=');
|
||||
|
||||
return !str.trim() ? obj : { ...obj, [key]: value };
|
||||
}, {});
|
||||
|
@ -21,10 +21,12 @@ export default () => {
|
|||
current[key] = params[key];
|
||||
}
|
||||
|
||||
return Object.keys(current).map(key => `${key}=${current[key]}`).join('&');
|
||||
return Object.keys(current)
|
||||
.map((key) => `${key}=${current[key]}`)
|
||||
.join('&');
|
||||
};
|
||||
|
||||
const hash = useMemo((): Record<string, string> => getHashObject(location.hash), [ location.hash ]);
|
||||
const hash = useMemo((): Record<string, string> => getHashObject(location.hash), [location.hash]);
|
||||
|
||||
return { hash, pathTo };
|
||||
};
|
||||
|
|
|
@ -2,23 +2,21 @@ import { ServerContext } from '@/state/server';
|
|||
import { useDeepCompareMemo } from '@/plugins/useDeepCompareMemo';
|
||||
|
||||
export const usePermissions = (action: string | string[]): boolean[] => {
|
||||
const userPermissions = ServerContext.useStoreState(state => state.server.permissions);
|
||||
const userPermissions = ServerContext.useStoreState((state) => state.server.permissions);
|
||||
|
||||
return useDeepCompareMemo(() => {
|
||||
if (userPermissions[0] === '*') {
|
||||
return Array(Array.isArray(action) ? action.length : 1).fill(true);
|
||||
}
|
||||
|
||||
return (Array.isArray(action) ? action : [ action ])
|
||||
.map(permission => (
|
||||
return (Array.isArray(action) ? action : [action]).map(
|
||||
(permission) =>
|
||||
// Allows checking for any permission matching a name, for example files.*
|
||||
// will return if the user has any permission under the file.XYZ namespace.
|
||||
(
|
||||
permission.endsWith('.*') &&
|
||||
userPermissions.filter(p => p.startsWith(permission.split('.')[0])).length > 0
|
||||
) ||
|
||||
(permission.endsWith('.*') &&
|
||||
userPermissions.filter((p) => p.startsWith(permission.split('.')[0])).length > 0) ||
|
||||
// Otherwise just check if the entire permission exists in the array or not.
|
||||
userPermissions.indexOf(permission) >= 0
|
||||
));
|
||||
}, [ action, userPermissions ]);
|
||||
);
|
||||
}, [action, userPermissions]);
|
||||
};
|
||||
|
|
|
@ -1,23 +1,24 @@
|
|||
import { Dispatch, SetStateAction, useEffect, useState } from 'react';
|
||||
|
||||
export function usePersistedState<S = undefined> (key: string, defaultValue: S): [ S | undefined, Dispatch<SetStateAction<S | undefined>> ] {
|
||||
const [ state, setState ] = useState(
|
||||
() => {
|
||||
try {
|
||||
const item = localStorage.getItem(key);
|
||||
export function usePersistedState<S = undefined>(
|
||||
key: string,
|
||||
defaultValue: S
|
||||
): [S | undefined, Dispatch<SetStateAction<S | undefined>>] {
|
||||
const [state, setState] = useState(() => {
|
||||
try {
|
||||
const item = localStorage.getItem(key);
|
||||
|
||||
return JSON.parse(item || (String(defaultValue)));
|
||||
} catch (e) {
|
||||
console.warn('Failed to retrieve persisted value from store.', e);
|
||||
return JSON.parse(item || String(defaultValue));
|
||||
} catch (e) {
|
||||
console.warn('Failed to retrieve persisted value from store.', e);
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
},
|
||||
);
|
||||
return defaultValue;
|
||||
}
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
localStorage.setItem(key, JSON.stringify(state));
|
||||
}, [ key, state ]);
|
||||
}, [key, state]);
|
||||
|
||||
return [ state, setState ];
|
||||
return [state, setState];
|
||||
}
|
||||
|
|
|
@ -3,12 +3,10 @@ import { useDeepCompareMemo } from '@/plugins/useDeepCompareMemo';
|
|||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
export default (context: string | string[] | (string | number | null | {})[]) => {
|
||||
const uuid = useStoreState(state => state.user.data?.uuid);
|
||||
const uuid = useStoreState((state) => state.user.data?.uuid);
|
||||
const key = useDeepCompareMemo((): string => {
|
||||
return (Array.isArray(context) ? context : [ context ])
|
||||
.map((value) => JSON.stringify(value))
|
||||
.join(':');
|
||||
}, [ context ]);
|
||||
return (Array.isArray(context) ? context : [context]).map((value) => JSON.stringify(value)).join(':');
|
||||
}, [context]);
|
||||
|
||||
if (!key.trim().length) {
|
||||
throw new Error('Must provide a valid context key to "useUserSWRContextKey".');
|
||||
|
|
|
@ -3,12 +3,12 @@ import { useEffect, useRef } from 'react';
|
|||
import { SocketEvent } from '@/components/server/events';
|
||||
|
||||
const useWebsocketEvent = (event: SocketEvent, callback: (data: string) => void) => {
|
||||
const { connected, instance } = ServerContext.useStoreState(state => state.socket);
|
||||
const { connected, instance } = ServerContext.useStoreState((state) => state.socket);
|
||||
const savedCallback = useRef<any>(null);
|
||||
|
||||
useEffect(() => {
|
||||
savedCallback.current = callback;
|
||||
}, [ callback ]);
|
||||
}, [callback]);
|
||||
|
||||
return useEffect(() => {
|
||||
const eventListener = (event: SocketEvent) => savedCallback.current(event);
|
||||
|
@ -19,7 +19,7 @@ const useWebsocketEvent = (event: SocketEvent, callback: (data: string) => void)
|
|||
return () => {
|
||||
instance && instance.removeListener(event, eventListener);
|
||||
};
|
||||
}, [ event, connected, instance ]);
|
||||
}, [event, connected, instance]);
|
||||
};
|
||||
|
||||
export default useWebsocketEvent;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue