Message Requests: Add new "Report spam and block" button
This commit is contained in:
parent
20e501d9f1
commit
d4dc9b8e39
33 changed files with 630 additions and 92 deletions
30
ts/util/connectToServerWithStoredCredentials.ts
Normal file
30
ts/util/connectToServerWithStoredCredentials.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import type { WebAPIConnectType, WebAPIType } from '../textsecure/WebAPI';
|
||||
|
||||
// We define a stricter storage here that returns `unknown` instead of `any`.
|
||||
type Storage = {
|
||||
get(key: string): unknown;
|
||||
};
|
||||
|
||||
export function connectToServerWithStoredCredentials(
|
||||
WebAPI: WebAPIConnectType,
|
||||
storage: Storage
|
||||
): WebAPIType {
|
||||
const username = storage.get('uuid_id') || storage.get('number_id');
|
||||
if (typeof username !== 'string') {
|
||||
throw new Error(
|
||||
'Username in storage was not a string. Cannot connect to WebAPI'
|
||||
);
|
||||
}
|
||||
|
||||
const password = storage.get('password');
|
||||
if (typeof password !== 'string') {
|
||||
throw new Error(
|
||||
'Password in storage was not a string. Cannot connect to WebAPI'
|
||||
);
|
||||
}
|
||||
|
||||
return WebAPI.connect({ username, password });
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
import * as React from 'react';
|
||||
import { ActionCreatorsMapObject, bindActionCreators } from 'redux';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { first, last, noop } from 'lodash';
|
||||
|
||||
export function usePrevious<T>(initialValue: T, currentValue: T): T {
|
||||
const previousValueRef = React.useRef<T>(initialValue);
|
||||
|
@ -132,3 +133,57 @@ export function useIntersectionObserver(): [
|
|||
|
||||
return [setRef, intersectionObserverEntry];
|
||||
}
|
||||
|
||||
function getTop(element: Readonly<Element>): number {
|
||||
return element.getBoundingClientRect().top;
|
||||
}
|
||||
|
||||
function isWrapped(element: Readonly<null | HTMLElement>): boolean {
|
||||
if (!element) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const { children } = element;
|
||||
const firstChild = first(children);
|
||||
const lastChild = last(children);
|
||||
|
||||
return Boolean(
|
||||
firstChild &&
|
||||
lastChild &&
|
||||
firstChild !== lastChild &&
|
||||
getTop(firstChild) !== getTop(lastChild)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* A hook that returns a ref (to put on your element) and a boolean. The boolean will be
|
||||
* `true` if the element's children have different `top`s, and `false` otherwise.
|
||||
*/
|
||||
export function useHasWrapped<T extends HTMLElement>(): [
|
||||
React.Ref<T>,
|
||||
boolean
|
||||
] {
|
||||
const [element, setElement] = React.useState<null | T>(null);
|
||||
|
||||
const [hasWrapped, setHasWrapped] = React.useState(isWrapped(element));
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!element) {
|
||||
return noop;
|
||||
}
|
||||
|
||||
// We can remove this `any` when we upgrade to TypeScript 4.2+, which adds
|
||||
// `ResizeObserver` type definitions.
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const observer = new (window as any).ResizeObserver(() => {
|
||||
setHasWrapped(isWrapped(element));
|
||||
});
|
||||
observer.observe(element);
|
||||
|
||||
return () => {
|
||||
observer.disconnect();
|
||||
};
|
||||
}, [element]);
|
||||
|
||||
return [setElement, hasWrapped];
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue