Display SMS/MMS disclaimer in empty search results

This commit is contained in:
Fedor Indutny 2021-05-19 09:14:35 -07:00 committed by Scott Nonnenberg
parent d1d53b645d
commit 80da8bb47b
10 changed files with 113 additions and 16 deletions

View file

@ -739,6 +739,10 @@
} }
} }
}, },
"noSearchResults--sms-only": {
"message": "SMS/MMS contacts are not available on Desktop.",
"description": "Shown in the search left pane when no results were found and primary device has SMS/MMS handling enabled"
},
"noSearchResultsInConversation": { "noSearchResultsInConversation": {
"message": "No results for \"$searchTerm$\" in $conversationName$", "message": "No results for \"$searchTerm$\" in $conversationName$",
"description": "Shown in the search left pane when no results were found", "description": "Shown in the search left pane when no results were found",

View file

@ -129,4 +129,5 @@ message AccountRecord {
optional PhoneNumberSharingMode phoneNumberSharingMode = 12; optional PhoneNumberSharingMode phoneNumberSharingMode = 12;
optional bool notDiscoverableByPhoneNumber = 13; optional bool notDiscoverableByPhoneNumber = 13;
repeated PinnedConversation pinnedConversations = 14; repeated PinnedConversation pinnedConversations = 14;
optional bool primarySendsSms = 18;
} }

View file

@ -7331,6 +7331,16 @@ button.module-image__border-overlay:focus {
outline: none; outline: none;
} }
.module-left-pane__no-search-results__sms-only {
margin-top: 12px;
@include light-theme {
color: $color-gray-60;
}
@include dark-theme {
color: $color-gray-25;
}
}
.module-left-pane__compose-search-form { .module-left-pane__compose-search-form {
&__input { &__input {
flex-grow: 1; flex-grow: 1;

View file

@ -249,6 +249,22 @@ story.add('Search: no results when searching everywhere', () => (
contactResults: emptySearchResultsGroup, contactResults: emptySearchResultsGroup,
messageResults: emptySearchResultsGroup, messageResults: emptySearchResultsGroup,
searchTerm: 'foo bar', searchTerm: 'foo bar',
primarySendsSms: false,
},
})}
/>
));
story.add('Search: no results when searching everywhere (SMS)', () => (
<LeftPane
{...createProps({
modeSpecificProps: {
mode: LeftPaneMode.Search,
conversationResults: emptySearchResultsGroup,
contactResults: emptySearchResultsGroup,
messageResults: emptySearchResultsGroup,
searchTerm: 'foo bar',
primarySendsSms: true,
}, },
})} })}
/> />
@ -264,6 +280,7 @@ story.add('Search: no results when searching in a conversation', () => (
messageResults: emptySearchResultsGroup, messageResults: emptySearchResultsGroup,
searchConversationName: 'Bing Bong', searchConversationName: 'Bing Bong',
searchTerm: 'foo bar', searchTerm: 'foo bar',
primarySendsSms: false,
}, },
})} })}
/> />
@ -278,6 +295,7 @@ story.add('Search: all results loading', () => (
contactResults: { isLoading: true }, contactResults: { isLoading: true },
messageResults: { isLoading: true }, messageResults: { isLoading: true },
searchTerm: 'foo bar', searchTerm: 'foo bar',
primarySendsSms: false,
}, },
})} })}
/> />
@ -295,6 +313,7 @@ story.add('Search: some results loading', () => (
contactResults: { isLoading: true }, contactResults: { isLoading: true },
messageResults: { isLoading: true }, messageResults: { isLoading: true },
searchTerm: 'foo bar', searchTerm: 'foo bar',
primarySendsSms: false,
}, },
})} })}
/> />
@ -312,6 +331,7 @@ story.add('Search: has conversations and contacts, but not messages', () => (
contactResults: { isLoading: false, results: defaultConversations }, contactResults: { isLoading: false, results: defaultConversations },
messageResults: { isLoading: false, results: [] }, messageResults: { isLoading: false, results: [] },
searchTerm: 'foo bar', searchTerm: 'foo bar',
primarySendsSms: false,
}, },
})} })}
/> />
@ -335,6 +355,7 @@ story.add('Search: all results', () => (
], ],
}, },
searchTerm: 'foo bar', searchTerm: 'foo bar',
primarySendsSms: false,
}, },
})} })}
/> />

View file

@ -31,6 +31,7 @@ export type LeftPaneSearchPropsType = {
conversationId: string; conversationId: string;
}>; }>;
searchConversationName?: string; searchConversationName?: string;
primarySendsSms: boolean;
searchTerm: string; searchTerm: string;
}; };
@ -50,6 +51,8 @@ export class LeftPaneSearchHelper extends LeftPaneHelper<LeftPaneSearchPropsType
private readonly searchConversationName?: string; private readonly searchConversationName?: string;
private readonly primarySendsSms: boolean;
private readonly searchTerm: string; private readonly searchTerm: string;
constructor({ constructor({
@ -57,6 +60,7 @@ export class LeftPaneSearchHelper extends LeftPaneHelper<LeftPaneSearchPropsType
contactResults, contactResults,
messageResults, messageResults,
searchConversationName, searchConversationName,
primarySendsSms,
searchTerm, searchTerm,
}: Readonly<LeftPaneSearchPropsType>) { }: Readonly<LeftPaneSearchPropsType>) {
super(); super();
@ -65,6 +69,7 @@ export class LeftPaneSearchHelper extends LeftPaneHelper<LeftPaneSearchPropsType
this.contactResults = contactResults; this.contactResults = contactResults;
this.messageResults = messageResults; this.messageResults = messageResults;
this.searchConversationName = searchConversationName; this.searchConversationName = searchConversationName;
this.primarySendsSms = primarySendsSms;
this.searchTerm = searchTerm; this.searchTerm = searchTerm;
} }
@ -78,7 +83,34 @@ export class LeftPaneSearchHelper extends LeftPaneHelper<LeftPaneSearchPropsType
return null; return null;
} }
const { searchConversationName, searchTerm } = this; const { searchConversationName, primarySendsSms, searchTerm } = this;
let noResults: ReactChild;
if (searchConversationName) {
noResults = (
<Intl
id="noSearchResultsInConversation"
i18n={i18n}
components={{
searchTerm,
conversationName: (
<Emojify key="item-1" text={searchConversationName} />
),
}}
/>
);
} else {
noResults = (
<>
<div>{i18n('noSearchResults', [searchTerm])}</div>
{primarySendsSms && (
<div className="module-left-pane__no-search-results__sms-only">
{i18n('noSearchResults--sms-only')}
</div>
)}
</>
);
}
return !searchConversationName || searchTerm ? ( return !searchConversationName || searchTerm ? (
<div <div
@ -87,20 +119,7 @@ export class LeftPaneSearchHelper extends LeftPaneHelper<LeftPaneSearchPropsType
className="module-left-pane__no-search-results" className="module-left-pane__no-search-results"
key={searchTerm} key={searchTerm}
> >
{searchConversationName ? ( {noResults}
<Intl
id="noSearchResultsInConversation"
i18n={i18n}
components={{
searchTerm,
conversationName: (
<Emojify key="item-1" text={searchConversationName} />
),
}}
/>
) : (
i18n('noSearchResults', [searchTerm])
)}
</div> </div>
) : null; ) : null;
} }

View file

@ -177,6 +177,11 @@ export async function toAccountRecord(
); );
accountRecord.linkPreviews = Boolean(window.storage.get('linkPreviews')); accountRecord.linkPreviews = Boolean(window.storage.get('linkPreviews'));
const primarySendsSms = window.storage.get('primarySendsSms');
if (primarySendsSms !== undefined) {
accountRecord.primarySendsSms = Boolean(primarySendsSms);
}
const PHONE_NUMBER_SHARING_MODE_ENUM = const PHONE_NUMBER_SHARING_MODE_ENUM =
window.textsecure.protobuf.AccountRecord.PhoneNumberSharingMode; window.textsecure.protobuf.AccountRecord.PhoneNumberSharingMode;
const phoneNumberSharingMode = parsePhoneNumberSharingMode( const phoneNumberSharingMode = parsePhoneNumberSharingMode(
@ -805,6 +810,7 @@ export async function mergeAccountRecord(
readReceipts, readReceipts,
sealedSenderIndicators, sealedSenderIndicators,
typingIndicators, typingIndicators,
primarySendsSms,
} = accountRecord; } = accountRecord;
window.storage.put('read-receipt-setting', readReceipts); window.storage.put('read-receipt-setting', readReceipts);
@ -821,6 +827,10 @@ export async function mergeAccountRecord(
window.storage.put('linkPreviews', linkPreviews); window.storage.put('linkPreviews', linkPreviews);
} }
if (typeof primarySendsSms === 'boolean') {
window.storage.put('primarySendsSms', primarySendsSms);
}
const PHONE_NUMBER_SHARING_MODE_ENUM = const PHONE_NUMBER_SHARING_MODE_ENUM =
window.textsecure.protobuf.AccountRecord.PhoneNumberSharingMode; window.textsecure.protobuf.AccountRecord.PhoneNumberSharingMode;
let phoneNumberSharingModeToStore: PhoneNumberSharingMode; let phoneNumberSharingModeToStore: PhoneNumberSharingMode;

View file

@ -72,7 +72,7 @@ export const getSearchResults = createSelector(
( (
state: SearchStateType, state: SearchStateType,
conversationLookup: ConversationLookupType conversationLookup: ConversationLookupType
): LeftPaneSearchPropsType => { ): Omit<LeftPaneSearchPropsType, 'primarySendsSms'> => {
const { const {
contactIds, contactIds,
conversationIds, conversationIds,

View file

@ -3,6 +3,7 @@
import React, { CSSProperties } from 'react'; import React, { CSSProperties } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { get } from 'lodash';
import { mapDispatchToProps } from '../actions'; import { mapDispatchToProps } from '../actions';
import { import {
LeftPane, LeftPane,
@ -88,8 +89,13 @@ const getModeSpecificProps = (
}; };
} }
if (isSearching(state)) { if (isSearching(state)) {
const primarySendsSms = Boolean(
get(state.items, ['primarySendsSms'], false)
);
return { return {
mode: LeftPaneMode.Search, mode: LeftPaneMode.Search,
primarySendsSms,
...getSearchResults(state), ...getSearchResults(state),
}; };
} }

View file

@ -22,6 +22,7 @@ describe('LeftPaneSearchHelper', () => {
contactResults: { isLoading: false, results: [] }, contactResults: { isLoading: false, results: [] },
messageResults: { isLoading: false, results: [] }, messageResults: { isLoading: false, results: [] },
searchTerm: 'foo', searchTerm: 'foo',
primarySendsSms: false,
}); });
assert.isUndefined( assert.isUndefined(
@ -42,6 +43,7 @@ describe('LeftPaneSearchHelper', () => {
contactResults: { isLoading: true }, contactResults: { isLoading: true },
messageResults: { isLoading: true }, messageResults: { isLoading: true },
searchTerm: 'foo', searchTerm: 'foo',
primarySendsSms: false,
}).getRowCount(), }).getRowCount(),
100 100
); );
@ -54,6 +56,7 @@ describe('LeftPaneSearchHelper', () => {
contactResults: { isLoading: true }, contactResults: { isLoading: true },
messageResults: { isLoading: true }, messageResults: { isLoading: true },
searchTerm: 'foo', searchTerm: 'foo',
primarySendsSms: false,
}).getRowCount(), }).getRowCount(),
100 100
); );
@ -63,6 +66,7 @@ describe('LeftPaneSearchHelper', () => {
contactResults: { isLoading: true }, contactResults: { isLoading: true },
messageResults: { isLoading: false, results: [fakeMessage()] }, messageResults: { isLoading: false, results: [fakeMessage()] },
searchTerm: 'foo', searchTerm: 'foo',
primarySendsSms: false,
}).getRowCount(), }).getRowCount(),
100 100
); );
@ -74,6 +78,7 @@ describe('LeftPaneSearchHelper', () => {
contactResults: { isLoading: false, results: [] }, contactResults: { isLoading: false, results: [] },
messageResults: { isLoading: false, results: [] }, messageResults: { isLoading: false, results: [] },
searchTerm: 'foo', searchTerm: 'foo',
primarySendsSms: false,
}); });
assert.strictEqual(helper.getRowCount(), 0); assert.strictEqual(helper.getRowCount(), 0);
@ -88,6 +93,7 @@ describe('LeftPaneSearchHelper', () => {
contactResults: { isLoading: false, results: [] }, contactResults: { isLoading: false, results: [] },
messageResults: { isLoading: false, results: [fakeMessage()] }, messageResults: { isLoading: false, results: [fakeMessage()] },
searchTerm: 'foo', searchTerm: 'foo',
primarySendsSms: false,
}); });
assert.strictEqual(helper.getRowCount(), 5); assert.strictEqual(helper.getRowCount(), 5);
@ -102,6 +108,7 @@ describe('LeftPaneSearchHelper', () => {
contactResults: { isLoading: true }, contactResults: { isLoading: true },
messageResults: { isLoading: true }, messageResults: { isLoading: true },
searchTerm: 'foo', searchTerm: 'foo',
primarySendsSms: false,
}), }),
new LeftPaneSearchHelper({ new LeftPaneSearchHelper({
conversationResults: { conversationResults: {
@ -111,12 +118,14 @@ describe('LeftPaneSearchHelper', () => {
contactResults: { isLoading: true }, contactResults: { isLoading: true },
messageResults: { isLoading: true }, messageResults: { isLoading: true },
searchTerm: 'foo', searchTerm: 'foo',
primarySendsSms: false,
}), }),
new LeftPaneSearchHelper({ new LeftPaneSearchHelper({
conversationResults: { isLoading: true }, conversationResults: { isLoading: true },
contactResults: { isLoading: true }, contactResults: { isLoading: true },
messageResults: { isLoading: false, results: [fakeMessage()] }, messageResults: { isLoading: false, results: [fakeMessage()] },
searchTerm: 'foo', searchTerm: 'foo',
primarySendsSms: false,
}), }),
]; ];
@ -149,6 +158,7 @@ describe('LeftPaneSearchHelper', () => {
contactResults: { isLoading: false, results: contacts }, contactResults: { isLoading: false, results: contacts },
messageResults: { isLoading: false, results: messages }, messageResults: { isLoading: false, results: messages },
searchTerm: 'foo', searchTerm: 'foo',
primarySendsSms: false,
}); });
assert.deepEqual(helper.getRow(0), { assert.deepEqual(helper.getRow(0), {
@ -197,6 +207,7 @@ describe('LeftPaneSearchHelper', () => {
contactResults: { isLoading: false, results: contacts }, contactResults: { isLoading: false, results: contacts },
messageResults: { isLoading: false, results: messages }, messageResults: { isLoading: false, results: messages },
searchTerm: 'foo', searchTerm: 'foo',
primarySendsSms: false,
}); });
assert.deepEqual(helper.getRow(0), { assert.deepEqual(helper.getRow(0), {
@ -236,6 +247,7 @@ describe('LeftPaneSearchHelper', () => {
contactResults: { isLoading: false, results: [] }, contactResults: { isLoading: false, results: [] },
messageResults: { isLoading: false, results: messages }, messageResults: { isLoading: false, results: messages },
searchTerm: 'foo', searchTerm: 'foo',
primarySendsSms: false,
}); });
assert.deepEqual(helper.getRow(0), { assert.deepEqual(helper.getRow(0), {
@ -277,6 +289,7 @@ describe('LeftPaneSearchHelper', () => {
contactResults: { isLoading: false, results: contacts }, contactResults: { isLoading: false, results: contacts },
messageResults: { isLoading: false, results: [] }, messageResults: { isLoading: false, results: [] },
searchTerm: 'foo', searchTerm: 'foo',
primarySendsSms: false,
}); });
assert.deepEqual(helper.getRow(0), { assert.deepEqual(helper.getRow(0), {
@ -310,6 +323,7 @@ describe('LeftPaneSearchHelper', () => {
contactResults: { isLoading: true }, contactResults: { isLoading: true },
messageResults: { isLoading: true }, messageResults: { isLoading: true },
searchTerm: 'foo', searchTerm: 'foo',
primarySendsSms: false,
}), }),
new LeftPaneSearchHelper({ new LeftPaneSearchHelper({
conversationResults: { conversationResults: {
@ -319,12 +333,14 @@ describe('LeftPaneSearchHelper', () => {
contactResults: { isLoading: true }, contactResults: { isLoading: true },
messageResults: { isLoading: true }, messageResults: { isLoading: true },
searchTerm: 'foo', searchTerm: 'foo',
primarySendsSms: false,
}), }),
new LeftPaneSearchHelper({ new LeftPaneSearchHelper({
conversationResults: { isLoading: true }, conversationResults: { isLoading: true },
contactResults: { isLoading: true }, contactResults: { isLoading: true },
messageResults: { isLoading: false, results: [fakeMessage()] }, messageResults: { isLoading: false, results: [fakeMessage()] },
searchTerm: 'foo', searchTerm: 'foo',
primarySendsSms: false,
}), }),
]; ];
@ -345,6 +361,7 @@ describe('LeftPaneSearchHelper', () => {
results: [fakeMessage(), fakeMessage(), fakeMessage()], results: [fakeMessage(), fakeMessage(), fakeMessage()],
}, },
searchTerm: 'foo', searchTerm: 'foo',
primarySendsSms: false,
}); });
assert.isTrue(helper.isScrollable()); assert.isTrue(helper.isScrollable());
}); });
@ -363,6 +380,7 @@ describe('LeftPaneSearchHelper', () => {
results: [fakeMessage(), fakeMessage(), fakeMessage()], results: [fakeMessage(), fakeMessage(), fakeMessage()],
}, },
searchTerm: 'foo', searchTerm: 'foo',
primarySendsSms: false,
}); });
assert.isFalse( assert.isFalse(
@ -377,6 +395,7 @@ describe('LeftPaneSearchHelper', () => {
results: [fakeMessage(), fakeMessage(), fakeMessage()], results: [fakeMessage(), fakeMessage(), fakeMessage()],
}, },
searchTerm: 'bar', searchTerm: 'bar',
primarySendsSms: false,
}) })
); );
}); });
@ -387,6 +406,7 @@ describe('LeftPaneSearchHelper', () => {
contactResults: { isLoading: true }, contactResults: { isLoading: true },
messageResults: { isLoading: true }, messageResults: { isLoading: true },
searchTerm: 'foo', searchTerm: 'foo',
primarySendsSms: false,
}); });
assert.isFalse( assert.isFalse(
@ -398,6 +418,7 @@ describe('LeftPaneSearchHelper', () => {
contactResults: { isLoading: true }, contactResults: { isLoading: true },
messageResults: { isLoading: true }, messageResults: { isLoading: true },
searchTerm: 'bar', searchTerm: 'bar',
primarySendsSms: false,
}) })
); );
}); });
@ -408,6 +429,7 @@ describe('LeftPaneSearchHelper', () => {
contactResults: { isLoading: true }, contactResults: { isLoading: true },
messageResults: { isLoading: false, results: [fakeMessage()] }, messageResults: { isLoading: false, results: [fakeMessage()] },
searchTerm: 'foo', searchTerm: 'foo',
primarySendsSms: false,
}); });
assert.isTrue( assert.isTrue(
@ -419,6 +441,7 @@ describe('LeftPaneSearchHelper', () => {
contactResults: { isLoading: false, results: [] }, contactResults: { isLoading: false, results: [] },
messageResults: { isLoading: false, results: [fakeMessage()] }, messageResults: { isLoading: false, results: [fakeMessage()] },
searchTerm: 'foo', searchTerm: 'foo',
primarySendsSms: false,
}) })
); );
}); });
@ -432,6 +455,7 @@ describe('LeftPaneSearchHelper', () => {
contactResults: { isLoading: false, results: [] }, contactResults: { isLoading: false, results: [] },
messageResults: { isLoading: false, results: [] }, messageResults: { isLoading: false, results: [] },
searchTerm: 'foo', searchTerm: 'foo',
primarySendsSms: false,
}); });
assert.isTrue( assert.isTrue(
@ -443,6 +467,7 @@ describe('LeftPaneSearchHelper', () => {
contactResults: { isLoading: true }, contactResults: { isLoading: true },
messageResults: { isLoading: true }, messageResults: { isLoading: true },
searchTerm: 'bar', searchTerm: 'bar',
primarySendsSms: false,
}) })
); );
}); });

1
ts/textsecure.d.ts vendored
View file

@ -1060,6 +1060,7 @@ export declare class AccountRecordClass {
notDiscoverableByPhoneNumber?: boolean; notDiscoverableByPhoneNumber?: boolean;
pinnedConversations?: PinnedConversationClass[]; pinnedConversations?: PinnedConversationClass[];
noteToSelfMarkedUnread?: boolean; noteToSelfMarkedUnread?: boolean;
primarySendsSms?: boolean;
__unknownFields?: ArrayBuffer; __unknownFields?: ArrayBuffer;
} }