Improve experience for contacts without signal accounts
This commit is contained in:
parent
fe505a7f2f
commit
7fa730531a
11 changed files with 266 additions and 3 deletions
|
@ -4615,6 +4615,18 @@
|
||||||
"message": "Attach file",
|
"message": "Attach file",
|
||||||
"description": "Aria label for file attachment button in composition area"
|
"description": "Aria label for file attachment button in composition area"
|
||||||
},
|
},
|
||||||
|
"CompositionArea--sms-only__title": {
|
||||||
|
"message": "This person isn’t using Signal",
|
||||||
|
"description": "Title for the composition area for the SMS-only contact"
|
||||||
|
},
|
||||||
|
"CompositionArea--sms-only__body": {
|
||||||
|
"message": "Signal Desktop does not support messaging non-Signal contacts. Ask this person to install Signal for a more secure messaging experience.",
|
||||||
|
"description": "Body for the composition area for the SMS-only contact"
|
||||||
|
},
|
||||||
|
"CompositionArea--sms-only__spinner-label": {
|
||||||
|
"message": "Checking contact's registration status",
|
||||||
|
"description": "Displayed while checking if the contact is SMS-only"
|
||||||
|
},
|
||||||
"countMutedConversationsDescription": {
|
"countMutedConversationsDescription": {
|
||||||
"message": "Count muted conversations in badge count",
|
"message": "Count muted conversations in badge count",
|
||||||
"description": "Description for counting muted conversations in badge setting"
|
"description": "Description for counting muted conversations in badge setting"
|
||||||
|
|
|
@ -9250,6 +9250,50 @@ button.module-image__border-overlay:focus {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.module-composition-area--sms-only {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
// Note the margine in .composition-area-placeholder above
|
||||||
|
padding: 14px 16px 18px 16px;
|
||||||
|
|
||||||
|
&:not(.module-composition-area--pending) {
|
||||||
|
@include light-theme {
|
||||||
|
border-top: 1px solid $color-gray-05;
|
||||||
|
}
|
||||||
|
@include dark-theme {
|
||||||
|
border-top: 1px solid $color-gray-75;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__title {
|
||||||
|
@include font-body-2-bold;
|
||||||
|
margin: 0 0 2px 0;
|
||||||
|
|
||||||
|
@include light-theme {
|
||||||
|
color: $color-gray-60;
|
||||||
|
}
|
||||||
|
@include dark-theme {
|
||||||
|
color: $color-gray-05;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__body {
|
||||||
|
@include font-body-2;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
@include light-theme {
|
||||||
|
color: $color-gray-60;
|
||||||
|
}
|
||||||
|
@include dark-theme {
|
||||||
|
color: $color-gray-05;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Module: Last Seen Indicator
|
// Module: Last Seen Indicator
|
||||||
|
|
||||||
.module-last-seen-indicator {
|
.module-last-seen-indicator {
|
||||||
|
|
|
@ -74,6 +74,9 @@ const createProps = (overrideProps: Partial<Props> = {}): Props => ({
|
||||||
onStartGroupMigration: action('onStartGroupMigration'),
|
onStartGroupMigration: action('onStartGroupMigration'),
|
||||||
// GroupV2 Pending Approval Actions
|
// GroupV2 Pending Approval Actions
|
||||||
onCancelJoinRequest: action('onCancelJoinRequest'),
|
onCancelJoinRequest: action('onCancelJoinRequest'),
|
||||||
|
// SMS-only
|
||||||
|
isSMSOnly: overrideProps.isSMSOnly || false,
|
||||||
|
isFetchingUUID: overrideProps.isFetchingUUID || false,
|
||||||
});
|
});
|
||||||
|
|
||||||
story.add('Default', () => {
|
story.add('Default', () => {
|
||||||
|
@ -106,3 +109,20 @@ story.add('Message Request', () => {
|
||||||
|
|
||||||
return <CompositionArea {...props} />;
|
return <CompositionArea {...props} />;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
story.add('SMS-only fetching UUID', () => {
|
||||||
|
const props = createProps({
|
||||||
|
isSMSOnly: true,
|
||||||
|
isFetchingUUID: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
return <CompositionArea {...props} />;
|
||||||
|
});
|
||||||
|
|
||||||
|
story.add('SMS-only', () => {
|
||||||
|
const props = createProps({
|
||||||
|
isSMSOnly: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
return <CompositionArea {...props} />;
|
||||||
|
});
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { get, noop } from 'lodash';
|
import { get, noop } from 'lodash';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
import { Spinner } from './Spinner';
|
||||||
import { EmojiButton, Props as EmojiButtonProps } from './emoji/EmojiButton';
|
import { EmojiButton, Props as EmojiButtonProps } from './emoji/EmojiButton';
|
||||||
import {
|
import {
|
||||||
Props as StickerButtonProps,
|
Props as StickerButtonProps,
|
||||||
|
@ -38,6 +39,8 @@ export type OwnProps = {
|
||||||
readonly groupVersion?: 1 | 2;
|
readonly groupVersion?: 1 | 2;
|
||||||
readonly isGroupV1AndDisabled?: boolean;
|
readonly isGroupV1AndDisabled?: boolean;
|
||||||
readonly isMissingMandatoryProfileSharing?: boolean;
|
readonly isMissingMandatoryProfileSharing?: boolean;
|
||||||
|
readonly isSMSOnly?: boolean;
|
||||||
|
readonly isFetchingUUID?: boolean;
|
||||||
readonly left?: boolean;
|
readonly left?: boolean;
|
||||||
readonly messageRequestsEnabled?: boolean;
|
readonly messageRequestsEnabled?: boolean;
|
||||||
readonly acceptedMessageRequest?: boolean;
|
readonly acceptedMessageRequest?: boolean;
|
||||||
|
@ -157,6 +160,9 @@ export const CompositionArea = ({
|
||||||
onStartGroupMigration,
|
onStartGroupMigration,
|
||||||
// GroupV2 Pending Approval Actions
|
// GroupV2 Pending Approval Actions
|
||||||
onCancelJoinRequest,
|
onCancelJoinRequest,
|
||||||
|
// SMS-only contacts
|
||||||
|
isSMSOnly,
|
||||||
|
isFetchingUUID,
|
||||||
}: Props): JSX.Element => {
|
}: Props): JSX.Element => {
|
||||||
const [disabled, setDisabled] = React.useState(false);
|
const [disabled, setDisabled] = React.useState(false);
|
||||||
const [showMic, setShowMic] = React.useState(!draftText);
|
const [showMic, setShowMic] = React.useState(!draftText);
|
||||||
|
@ -382,6 +388,36 @@ export const CompositionArea = ({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (conversationType === 'direct' && isSMSOnly) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={classNames([
|
||||||
|
'module-composition-area',
|
||||||
|
'module-composition-area--sms-only',
|
||||||
|
isFetchingUUID ? 'module-composition-area--pending' : null,
|
||||||
|
])}
|
||||||
|
>
|
||||||
|
{isFetchingUUID ? (
|
||||||
|
<Spinner
|
||||||
|
ariaLabel={i18n('CompositionArea--sms-only__spinner-label')}
|
||||||
|
role="presentation"
|
||||||
|
moduleClassName="module-image-spinner"
|
||||||
|
svgSize="small"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<h2 className="module-composition-area--sms-only__title">
|
||||||
|
{i18n('CompositionArea--sms-only__title')}
|
||||||
|
</h2>
|
||||||
|
<p className="module-composition-area--sms-only__body">
|
||||||
|
{i18n('CompositionArea--sms-only__body')}
|
||||||
|
</p>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// If no message request, but we haven't shared profile yet, we show profile-sharing UI
|
// If no message request, but we haven't shared profile yet, we show profile-sharing UI
|
||||||
if (
|
if (
|
||||||
!left &&
|
!left &&
|
||||||
|
|
|
@ -20,17 +20,21 @@ export const SpinnerDirections = [
|
||||||
export type SpinnerDirection = typeof SpinnerDirections[number];
|
export type SpinnerDirection = typeof SpinnerDirections[number];
|
||||||
|
|
||||||
export type Props = {
|
export type Props = {
|
||||||
moduleClassName?: string;
|
ariaLabel?: string;
|
||||||
direction?: SpinnerDirection;
|
direction?: SpinnerDirection;
|
||||||
|
moduleClassName?: string;
|
||||||
|
role?: string;
|
||||||
size?: string;
|
size?: string;
|
||||||
svgSize: SpinnerSvgSize;
|
svgSize: SpinnerSvgSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Spinner = ({
|
export const Spinner = ({
|
||||||
|
ariaLabel,
|
||||||
|
direction,
|
||||||
moduleClassName,
|
moduleClassName,
|
||||||
|
role,
|
||||||
size,
|
size,
|
||||||
svgSize,
|
svgSize,
|
||||||
direction,
|
|
||||||
}: Props): JSX.Element => {
|
}: Props): JSX.Element => {
|
||||||
const getClassName = getClassNamesFor('module-spinner', moduleClassName);
|
const getClassName = getClassNamesFor('module-spinner', moduleClassName);
|
||||||
|
|
||||||
|
@ -42,6 +46,8 @@ export const Spinner = ({
|
||||||
getClassName(direction && `__container--${direction}`),
|
getClassName(direction && `__container--${direction}`),
|
||||||
getClassName(direction && `__container--${svgSize}-${direction}`)
|
getClassName(direction && `__container--${svgSize}-${direction}`)
|
||||||
)}
|
)}
|
||||||
|
role={role}
|
||||||
|
aria-label={ariaLabel}
|
||||||
style={{
|
style={{
|
||||||
height: size,
|
height: size,
|
||||||
width: size,
|
width: size,
|
||||||
|
|
|
@ -23,6 +23,7 @@ import { ConversationType } from '../state/ducks/conversations';
|
||||||
import { ColorType } from '../types/Colors';
|
import { ColorType } from '../types/Colors';
|
||||||
import { MessageModel } from './messages';
|
import { MessageModel } from './messages';
|
||||||
import { isMuted } from '../util/isMuted';
|
import { isMuted } from '../util/isMuted';
|
||||||
|
import { isConversationSMSOnly } from '../util/isConversationSMSOnly';
|
||||||
import { isConversationUnregistered } from '../util/isConversationUnregistered';
|
import { isConversationUnregistered } from '../util/isConversationUnregistered';
|
||||||
import { missingCaseError } from '../util/missingCaseError';
|
import { missingCaseError } from '../util/missingCaseError';
|
||||||
import { sniffImageMimeType } from '../util/sniffImageMimeType';
|
import { sniffImageMimeType } from '../util/sniffImageMimeType';
|
||||||
|
@ -48,6 +49,7 @@ import { markConversationRead } from '../util/markConversationRead';
|
||||||
import { handleMessageSend } from '../util/handleMessageSend';
|
import { handleMessageSend } from '../util/handleMessageSend';
|
||||||
import { getConversationMembers } from '../util/getConversationMembers';
|
import { getConversationMembers } from '../util/getConversationMembers';
|
||||||
import { sendReadReceiptsFor } from '../util/sendReadReceiptsFor';
|
import { sendReadReceiptsFor } from '../util/sendReadReceiptsFor';
|
||||||
|
import { updateConversationsWithUuidLookup } from '../updateConversationsWithUuidLookup';
|
||||||
|
|
||||||
/* eslint-disable more/no-then */
|
/* eslint-disable more/no-then */
|
||||||
window.Whisper = window.Whisper || {};
|
window.Whisper = window.Whisper || {};
|
||||||
|
@ -88,6 +90,7 @@ const COLORS = [
|
||||||
];
|
];
|
||||||
|
|
||||||
const THREE_HOURS = 3 * 60 * 60 * 1000;
|
const THREE_HOURS = 3 * 60 * 60 * 1000;
|
||||||
|
const FIVE_MINUTES = 1000 * 60 * 5;
|
||||||
|
|
||||||
type CustomError = Error & {
|
type CustomError = Error & {
|
||||||
identifier?: string;
|
identifier?: string;
|
||||||
|
@ -140,6 +143,8 @@ export class ConversationModel extends window.Backbone
|
||||||
|
|
||||||
throttledBumpTyping: unknown;
|
throttledBumpTyping: unknown;
|
||||||
|
|
||||||
|
throttledFetchSMSOnlyUUID?: () => Promise<void> | void;
|
||||||
|
|
||||||
typingRefreshTimer?: NodeJS.Timer | null;
|
typingRefreshTimer?: NodeJS.Timer | null;
|
||||||
|
|
||||||
typingPauseTimer?: NodeJS.Timer | null;
|
typingPauseTimer?: NodeJS.Timer | null;
|
||||||
|
@ -154,6 +159,8 @@ export class ConversationModel extends window.Backbone
|
||||||
|
|
||||||
private cachedIdenticon?: CachedIdenticon;
|
private cachedIdenticon?: CachedIdenticon;
|
||||||
|
|
||||||
|
private isFetchingUUID?: boolean;
|
||||||
|
|
||||||
// eslint-disable-next-line class-methods-use-this
|
// eslint-disable-next-line class-methods-use-this
|
||||||
defaults(): Partial<ConversationAttributesType> {
|
defaults(): Partial<ConversationAttributesType> {
|
||||||
return {
|
return {
|
||||||
|
@ -281,6 +288,15 @@ export class ConversationModel extends window.Backbone
|
||||||
}
|
}
|
||||||
this.cachedProps = null;
|
this.cachedProps = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Set `isFetchingUUID` eagerly to avoid UI flicker when opening the
|
||||||
|
// conversation for the first time.
|
||||||
|
this.isFetchingUUID = this.isSMSOnly();
|
||||||
|
|
||||||
|
this.throttledFetchSMSOnlyUUID = window._.throttle(
|
||||||
|
this.fetchSMSOnlyUUID,
|
||||||
|
FIVE_MINUTES
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
isMe(): boolean {
|
isMe(): boolean {
|
||||||
|
@ -763,6 +779,13 @@ export class ConversationModel extends window.Backbone
|
||||||
return isConversationUnregistered(this.attributes);
|
return isConversationUnregistered(this.attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isSMSOnly(): boolean {
|
||||||
|
return isConversationSMSOnly({
|
||||||
|
...this.attributes,
|
||||||
|
type: this.isPrivate() ? 'direct' : 'unknown',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
setUnregistered(): void {
|
setUnregistered(): void {
|
||||||
window.log.info(`Conversation ${this.idForLogging()} is now unregistered`);
|
window.log.info(`Conversation ${this.idForLogging()} is now unregistered`);
|
||||||
this.set({
|
this.set({
|
||||||
|
@ -987,6 +1010,45 @@ export class ConversationModel extends window.Backbone
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fetchSMSOnlyUUID(): Promise<void> {
|
||||||
|
const { messaging } = window.textsecure;
|
||||||
|
if (!messaging) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!this.isSMSOnly()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.log.info(
|
||||||
|
`Fetching uuid for a sms-only conversation ${this.idForLogging()}`
|
||||||
|
);
|
||||||
|
|
||||||
|
this.isFetchingUUID = true;
|
||||||
|
this.trigger('change', this);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Attempt to fetch UUID
|
||||||
|
await updateConversationsWithUuidLookup({
|
||||||
|
conversationController: window.ConversationController,
|
||||||
|
conversations: [this],
|
||||||
|
messaging,
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
// No redux update here
|
||||||
|
this.isFetchingUUID = false;
|
||||||
|
this.trigger('change', this);
|
||||||
|
|
||||||
|
window.log.info(
|
||||||
|
`Done fetching uuid for a sms-only conversation ${this.idForLogging()}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// On successful fetch - mark contact as registered.
|
||||||
|
if (this.get('uuid')) {
|
||||||
|
this.setRegistered();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
isValid(): boolean {
|
isValid(): boolean {
|
||||||
return this.isPrivate() || this.isGroupV1() || this.isGroupV2();
|
return this.isPrivate() || this.isGroupV1() || this.isGroupV2();
|
||||||
}
|
}
|
||||||
|
@ -1358,6 +1420,7 @@ export class ConversationModel extends window.Backbone
|
||||||
isPinned: this.get('isPinned'),
|
isPinned: this.get('isPinned'),
|
||||||
isUntrusted: this.isUntrusted(),
|
isUntrusted: this.isUntrusted(),
|
||||||
isVerified: this.isVerified(),
|
isVerified: this.isVerified(),
|
||||||
|
isFetchingUUID: this.isFetchingUUID,
|
||||||
lastMessage: {
|
lastMessage: {
|
||||||
status: this.get('lastMessageStatus')!,
|
status: this.get('lastMessageStatus')!,
|
||||||
text: this.get('lastMessage')!,
|
text: this.get('lastMessage')!,
|
||||||
|
|
|
@ -114,6 +114,7 @@ export type ConversationType = {
|
||||||
searchableTitle?: string;
|
searchableTitle?: string;
|
||||||
unreadCount?: number;
|
unreadCount?: number;
|
||||||
isSelected?: boolean;
|
isSelected?: boolean;
|
||||||
|
isFetchingUUID?: boolean;
|
||||||
typingContact?: {
|
typingContact?: {
|
||||||
avatarPath?: string;
|
avatarPath?: string;
|
||||||
color?: ColorType;
|
color?: ColorType;
|
||||||
|
@ -568,7 +569,6 @@ export type ToggleConversationInChooseMembersActionType = {
|
||||||
maxGroupSize: number;
|
maxGroupSize: number;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ConversationActionType =
|
export type ConversationActionType =
|
||||||
| CantAddContactToGroupActionType
|
| CantAddContactToGroupActionType
|
||||||
| ClearChangedMessagesActionType
|
| ClearChangedMessagesActionType
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { get } from 'lodash';
|
||||||
import { mapDispatchToProps } from '../actions';
|
import { mapDispatchToProps } from '../actions';
|
||||||
import { CompositionArea } from '../../components/CompositionArea';
|
import { CompositionArea } from '../../components/CompositionArea';
|
||||||
import { StateType } from '../reducer';
|
import { StateType } from '../reducer';
|
||||||
|
import { isConversationSMSOnly } from '../../util/isConversationSMSOnly';
|
||||||
|
|
||||||
import { selectRecentEmojis } from '../selectors/emojis';
|
import { selectRecentEmojis } from '../selectors/emojis';
|
||||||
import { getIntl } from '../selectors/user';
|
import { getIntl } from '../selectors/user';
|
||||||
|
@ -72,6 +73,8 @@ const mapStateToProps = (state: StateType, props: ExternalProps) => {
|
||||||
// Message Requests
|
// Message Requests
|
||||||
...conversation,
|
...conversation,
|
||||||
conversationType: conversation.type,
|
conversationType: conversation.type,
|
||||||
|
isSMSOnly: Boolean(isConversationSMSOnly(conversation)),
|
||||||
|
isFetchingUUID: conversation.isFetchingUUID,
|
||||||
isMissingMandatoryProfileSharing: Boolean(
|
isMissingMandatoryProfileSharing: Boolean(
|
||||||
!conversation.profileSharing &&
|
!conversation.profileSharing &&
|
||||||
window.Signal.RemoteConfig.isEnabled(
|
window.Signal.RemoteConfig.isEnabled(
|
||||||
|
|
47
ts/test-both/util/isConversationSMSOnly_test.ts
Normal file
47
ts/test-both/util/isConversationSMSOnly_test.ts
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
// Copyright 2021 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
import { assert } from 'chai';
|
||||||
|
|
||||||
|
import { isConversationSMSOnly } from '../../util/isConversationSMSOnly';
|
||||||
|
|
||||||
|
describe('isConversationSMSOnly', () => {
|
||||||
|
it('returns false if passed an undefined discoveredUnregisteredAt', () => {
|
||||||
|
assert.isFalse(isConversationSMSOnly({}));
|
||||||
|
assert.isFalse(
|
||||||
|
isConversationSMSOnly({ discoveredUnregisteredAt: undefined })
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
['direct', 'private'].forEach(type => {
|
||||||
|
it(`returns true if passed a time fewer than 6 hours ago and is ${type}`, () => {
|
||||||
|
assert.isTrue(
|
||||||
|
isConversationSMSOnly({
|
||||||
|
type,
|
||||||
|
e164: 'e164',
|
||||||
|
uuid: 'uuid',
|
||||||
|
discoveredUnregisteredAt: Date.now(),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const fiveHours = 1000 * 60 * 60 * 5;
|
||||||
|
assert.isTrue(
|
||||||
|
isConversationSMSOnly({
|
||||||
|
type,
|
||||||
|
e164: 'e164',
|
||||||
|
uuid: 'uuid',
|
||||||
|
discoveredUnregisteredAt: Date.now() - fiveHours,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`returns true conversation is ${type} and has no uuid`, () => {
|
||||||
|
assert.isTrue(isConversationSMSOnly({ type, e164: 'e164' }));
|
||||||
|
assert.isFalse(isConversationSMSOnly({ type }));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns false for groups', () => {
|
||||||
|
assert.isFalse(isConversationSMSOnly({ type: 'group' }));
|
||||||
|
});
|
||||||
|
});
|
27
ts/util/isConversationSMSOnly.ts
Normal file
27
ts/util/isConversationSMSOnly.ts
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// Copyright 2021 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
import { isConversationUnregistered } from './isConversationUnregistered';
|
||||||
|
|
||||||
|
export type MinimalConversationType = Readonly<{
|
||||||
|
type?: string;
|
||||||
|
e164?: string;
|
||||||
|
uuid?: string;
|
||||||
|
discoveredUnregisteredAt?: number;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
export function isConversationSMSOnly(
|
||||||
|
conversation: MinimalConversationType
|
||||||
|
): boolean {
|
||||||
|
const { e164, uuid, type } = conversation;
|
||||||
|
// `direct` for redux, `private` for models and the database
|
||||||
|
if (type !== 'direct' && type !== 'private') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e164 && !uuid) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isConversationUnregistered(conversation);
|
||||||
|
}
|
|
@ -2178,6 +2178,11 @@ Whisper.ConversationView = Whisper.View.extend({
|
||||||
|
|
||||||
this.model.fetchLatestGroupV2Data();
|
this.model.fetchLatestGroupV2Data();
|
||||||
this.model.throttledMaybeMigrateV1Group();
|
this.model.throttledMaybeMigrateV1Group();
|
||||||
|
assert(
|
||||||
|
this.model.throttledFetchSMSOnlyUUID !== undefined,
|
||||||
|
'Conversation model should be initialized'
|
||||||
|
);
|
||||||
|
this.model.throttledFetchSMSOnlyUUID();
|
||||||
|
|
||||||
const statusPromise = this.model.throttledGetProfiles();
|
const statusPromise = this.model.throttledGetProfiles();
|
||||||
// eslint-disable-next-line more/no-then
|
// eslint-disable-next-line more/no-then
|
||||||
|
|
Loading…
Reference in a new issue