+
+
+
+
+));
+
story.add('Title, X button, body, and button footer', () => (
{LOREM_IPSUM}
@@ -69,6 +81,18 @@ story.add('Long body with title', () => (
));
+story.add('Long body with title and button', () => (
+
+
{LOREM_IPSUM}
+
{LOREM_IPSUM}
+
{LOREM_IPSUM}
+
{LOREM_IPSUM}
+
+
+
+
+));
+
story.add('Long body with long title and X button', () => (
-
+
-
-
-
-
-
+
+
+
+
+
);
}
diff --git a/ts/components/conversation/ReactionPicker.tsx b/ts/components/conversation/ReactionPicker.tsx
index 8042c61874..45f98091c8 100644
--- a/ts/components/conversation/ReactionPicker.tsx
+++ b/ts/components/conversation/ReactionPicker.tsx
@@ -6,7 +6,7 @@ import classNames from 'classnames';
import { Emoji } from '../emoji/Emoji';
import { convertShortName } from '../emoji/lib';
import { Props as EmojiPickerProps } from '../emoji/EmojiPicker';
-import { useRestoreFocus } from '../../util/hooks';
+import { useRestoreFocus } from '../../util/hooks/useRestoreFocus';
import { LocalizerType } from '../../types/Util';
export type RenderEmojiPickerProps = Pick &
diff --git a/ts/components/conversation/ReactionViewer.tsx b/ts/components/conversation/ReactionViewer.tsx
index 2f9d81df2e..81cb375b77 100644
--- a/ts/components/conversation/ReactionViewer.tsx
+++ b/ts/components/conversation/ReactionViewer.tsx
@@ -7,7 +7,7 @@ import classNames from 'classnames';
import { ContactName } from './ContactName';
import { Avatar, Props as AvatarProps } from '../Avatar';
import { Emoji } from '../emoji/Emoji';
-import { useRestoreFocus } from '../../util/hooks';
+import { useRestoreFocus } from '../../util/hooks/useRestoreFocus';
import { ConversationType } from '../../state/ducks/conversations';
import { emojiToData, EmojiData } from '../emoji/lib';
diff --git a/ts/components/stickers/StickerPicker.tsx b/ts/components/stickers/StickerPicker.tsx
index e6b21a2308..004caa47cd 100644
--- a/ts/components/stickers/StickerPicker.tsx
+++ b/ts/components/stickers/StickerPicker.tsx
@@ -3,7 +3,7 @@
import * as React from 'react';
import classNames from 'classnames';
-import { useRestoreFocus } from '../../util/hooks';
+import { useRestoreFocus } from '../../util/hooks/useRestoreFocus';
import { StickerPackType, StickerType } from '../../state/ducks/stickers';
import { LocalizerType } from '../../types/Util';
diff --git a/ts/components/stickers/StickerPreviewModal.tsx b/ts/components/stickers/StickerPreviewModal.tsx
index 1808f7ca49..8ff3224922 100644
--- a/ts/components/stickers/StickerPreviewModal.tsx
+++ b/ts/components/stickers/StickerPreviewModal.tsx
@@ -10,7 +10,7 @@ import { ConfirmationDialog } from '../ConfirmationDialog';
import { LocalizerType } from '../../types/Util';
import { StickerPackType } from '../../state/ducks/stickers';
import { Spinner } from '../Spinner';
-import { useRestoreFocus } from '../../util/hooks';
+import { useRestoreFocus } from '../../util/hooks/useRestoreFocus';
export type OwnProps = {
readonly onClose: () => unknown;
diff --git a/ts/models/messages.ts b/ts/models/messages.ts
index 64a4f26b33..905aa6ce65 100644
--- a/ts/models/messages.ts
+++ b/ts/models/messages.ts
@@ -1060,6 +1060,11 @@ export class MessageModel extends window.Backbone.Model {
if (isIncoming(this.attributes)) {
return this.get('source');
}
+ if (!isOutgoing(this.attributes)) {
+ window.log.warn(
+ 'Message.getSource: Called for non-incoming/non-outoing message'
+ );
+ }
return this.OUR_NUMBER;
}
@@ -1070,6 +1075,11 @@ export class MessageModel extends window.Backbone.Model {
if (isIncoming(this.attributes)) {
return sourceDevice;
}
+ if (!isOutgoing(this.attributes)) {
+ window.log.warn(
+ 'Message.getSourceDevice: Called for non-incoming/non-outoing message'
+ );
+ }
return sourceDevice || window.textsecure.storage.user.getDeviceId();
}
@@ -1078,6 +1088,11 @@ export class MessageModel extends window.Backbone.Model {
if (isIncoming(this.attributes)) {
return this.get('sourceUuid');
}
+ if (!isOutgoing(this.attributes)) {
+ window.log.warn(
+ 'Message.getSourceUuid: Called for non-incoming/non-outoing message'
+ );
+ }
return this.OUR_UUID;
}
diff --git a/ts/state/selectors/message.ts b/ts/state/selectors/message.ts
index a8ff2a0d15..2150ea389a 100644
--- a/ts/state/selectors/message.ts
+++ b/ts/state/selectors/message.ts
@@ -242,6 +242,11 @@ export function getSource(
if (isIncoming(message)) {
return message.source;
}
+ if (!isOutgoing(message)) {
+ window.log.warn(
+ 'message.getSource: Called for non-incoming/non-outoing message'
+ );
+ }
return ourNumber;
}
@@ -255,6 +260,11 @@ export function getSourceDevice(
if (isIncoming(message)) {
return sourceDevice;
}
+ if (!isOutgoing(message)) {
+ window.log.warn(
+ 'message.getSourceDevice: Called for non-incoming/non-outoing message'
+ );
+ }
return sourceDevice || ourDeviceId;
}
@@ -266,6 +276,11 @@ export function getSourceUuid(
if (isIncoming(message)) {
return message.sourceUuid;
}
+ if (!isOutgoing(message)) {
+ window.log.warn(
+ 'message.getSourceUuid: Called for non-incoming/non-outoing message'
+ );
+ }
return ourUuid;
}
diff --git a/ts/util/hooks.ts b/ts/util/hooks/index.ts
similarity index 75%
rename from ts/util/hooks.ts
rename to ts/util/hooks/index.ts
index 8567a96dca..10931a475e 100644
--- a/ts/util/hooks.ts
+++ b/ts/util/hooks/index.ts
@@ -13,49 +13,6 @@ export function usePrevious(initialValue: T, currentValue: T): T {
return result;
}
-type CallbackType = (toFocus: HTMLElement | null | undefined) => void;
-
-// Restore focus on teardown
-export const useRestoreFocus = (): Array => {
- const toFocusRef = React.useRef(null);
- const lastFocusedRef = React.useRef(null);
-
- // We need to use a callback here because refs aren't necessarily populated on first
- // render. For example, ModalHost makes a top-level parent div first, and then renders
- // into it. And the children you pass it don't have access to that root div.
- const setFocusRef = React.useCallback(
- (toFocus: HTMLElement | null | undefined) => {
- if (!toFocus) {
- return;
- }
-
- // We only want to do this once.
- if (toFocusRef.current) {
- return;
- }
- toFocusRef.current = toFocus;
-
- // Remember last-focused element, focus this new target element.
- lastFocusedRef.current = document.activeElement as HTMLElement;
- toFocus.focus();
- },
- []
- );
-
- React.useEffect(() => {
- return () => {
- // On unmount, returned focus to element focused before we set the focus
- setTimeout(() => {
- if (lastFocusedRef.current && lastFocusedRef.current.focus) {
- lastFocusedRef.current.focus();
- }
- });
- };
- }, []);
-
- return [setFocusRef];
-};
-
export const useBoundActions = (
actions: T
): T => {
diff --git a/ts/util/hooks/useRestoreFocus.ts b/ts/util/hooks/useRestoreFocus.ts
new file mode 100644
index 0000000000..02f82db0c7
--- /dev/null
+++ b/ts/util/hooks/useRestoreFocus.ts
@@ -0,0 +1,47 @@
+// Copyright 2021 Signal Messenger, LLC
+// SPDX-License-Identifier: AGPL-3.0-only
+
+import * as React from 'react';
+
+type CallbackType = (toFocus: HTMLElement | null | undefined) => void;
+
+// Restore focus on teardown
+export const useRestoreFocus = (): Array => {
+ const toFocusRef = React.useRef(null);
+ const lastFocusedRef = React.useRef(null);
+
+ // We need to use a callback here because refs aren't necessarily populated on first
+ // render. For example, ModalHost makes a top-level parent div first, and then renders
+ // into it. And the children you pass it don't have access to that root div.
+ const setFocusRef = React.useCallback(
+ (toFocus: HTMLElement | null | undefined) => {
+ if (!toFocus) {
+ return;
+ }
+
+ // We only want to do this once.
+ if (toFocusRef.current) {
+ return;
+ }
+ toFocusRef.current = toFocus;
+
+ // Remember last-focused element, focus this new target element.
+ lastFocusedRef.current = document.activeElement as HTMLElement;
+ toFocus.focus();
+ },
+ []
+ );
+
+ React.useEffect(() => {
+ return () => {
+ // On unmount, returned focus to element focused before we set the focus
+ setTimeout(() => {
+ if (lastFocusedRef.current && lastFocusedRef.current.focus) {
+ lastFocusedRef.current.focus();
+ }
+ });
+ };
+ }, []);
+
+ return [setFocusRef];
+};
diff --git a/ts/util/lint/exceptions.json b/ts/util/lint/exceptions.json
index 15c9da006c..f1272a2009 100644
--- a/ts/util/lint/exceptions.json
+++ b/ts/util/lint/exceptions.json
@@ -14398,7 +14398,7 @@
},
{
"rule": "React-useRef",
- "path": "ts/util/hooks.js",
+ "path": "ts/util/hooks/index.js",
"line": " const unobserveRef = React.useRef(null);",
"reasonCategory": "usageTrusted",
"updated": "2021-01-08T15:46:32.143Z",
@@ -14406,7 +14406,7 @@
},
{
"rule": "React-useRef",
- "path": "ts/util/hooks.js",
+ "path": "ts/util/hooks/index.js",
"line": " const previousValueRef = React.useRef(initialValue);",
"reasonCategory": "usageTrusted",
"updated": "2021-03-18T21:41:28.361Z",
@@ -14414,7 +14414,21 @@
},
{
"rule": "React-useRef",
- "path": "ts/util/hooks.js",
+ "path": "ts/util/hooks/index.ts",
+ "line": " const previousValueRef = React.useRef(initialValue);",
+ "reasonCategory": "usageTrusted",
+ "updated": "2021-07-30T16:57:33.618Z"
+ },
+ {
+ "rule": "React-useRef",
+ "path": "ts/util/hooks/index.ts",
+ "line": " const unobserveRef = React.useRef<(() => unknown) | null>(null);",
+ "reasonCategory": "usageTrusted",
+ "updated": "2021-07-30T16:57:33.618Z"
+ },
+ {
+ "rule": "React-useRef",
+ "path": "ts/util/hooks/useRestoreFocus.js",
"line": " const toFocusRef = React.useRef(null);",
"reasonCategory": "usageTrusted",
"updated": "2021-07-30T01:08:01.309Z",
@@ -14422,7 +14436,7 @@
},
{
"rule": "React-useRef",
- "path": "ts/util/hooks.js",
+ "path": "ts/util/hooks/useRestoreFocus.js",
"line": " const lastFocusedRef = React.useRef(null);",
"reasonCategory": "usageTrusted",
"updated": "2021-07-30T01:08:01.309Z",
@@ -14430,30 +14444,16 @@
},
{
"rule": "React-useRef",
- "path": "ts/util/hooks.ts",
- "line": " const previousValueRef = React.useRef(initialValue);",
- "reasonCategory": "usageTrusted",
- "updated": "2021-07-30T16:57:33.618Z"
- },
- {
- "rule": "React-useRef",
- "path": "ts/util/hooks.ts",
+ "path": "ts/util/hooks/useRestoreFocus.ts",
"line": " const toFocusRef = React.useRef(null);",
"reasonCategory": "usageTrusted",
"updated": "2021-07-30T16:57:33.618Z"
},
{
"rule": "React-useRef",
- "path": "ts/util/hooks.ts",
+ "path": "ts/util/hooks/useRestoreFocus.ts",
"line": " const lastFocusedRef = React.useRef(null);",
"reasonCategory": "usageTrusted",
"updated": "2021-07-30T16:57:33.618Z"
- },
- {
- "rule": "React-useRef",
- "path": "ts/util/hooks.ts",
- "line": " const unobserveRef = React.useRef<(() => unknown) | null>(null);",
- "reasonCategory": "usageTrusted",
- "updated": "2021-07-30T16:57:33.618Z"
}
]
\ No newline at end of file