New left pane search design
This commit is contained in:
parent
babd61377b
commit
bf45182a39
24 changed files with 500 additions and 359 deletions
1
images/icons/v2/compose-24.svg
Normal file
1
images/icons/v2/compose-24.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg fill="none" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="m20.29 2.75001c.0332-.00143.0664.00405.0974.0161.0309.01205.0591.0304.0826.0539l.71.71c.0235.02352.0419.05167.0539.08265.0121.03099.0175.06414.0161.09735.0001.03155-.0061.0628-.0181.09197s-.0296.05569-.0519.07803l-9.5 9.49999c-.0331.0315-.0749.0524-.12.06l-1.31.31.31-1.31c.0076-.0451.0285-.0868.06-.12l9.5-9.49999c.0223-.02226.0489-.03991.078-.05192.0292-.01201.0605-.01815.092-.01808zm0-1.75c-.5296.00224-1.0367.21442-1.41.59l-9.5 9.48999c-.26926.2754-.4533.6226-.53 1l-.75 3.22c-.01837.0727-.0198.1487-.0042.222s.04783.1421.0942.201c.04636.059.10564.1065.17325.1389.06762.0324.14177.0489.21675.0481h.12l3.3-.76c.3774-.0767.7246-.2607 1-.53l9.49-9.49999c.186-.18574.3335-.40632.4341-.64912.1007-.24279.1525-.50305.1525-.76588s-.0518-.52308-.1525-.76588c-.1006-.24279-.2481-.46337-.4341-.64912l-.7-.7c-.1954-.19702-.4297-.35122-.6879-.4528-.2583-.10157-.5348-.148296-.8121-.1372zm-6.79 2h-6.62c-1.29253 0-2.53226.51277-3.44715 1.42579-.91489.91301-1.4302 2.15169-1.43285 3.44421v9.24999c.00264 1.2935.51763 2.5332 1.43224 3.4478.9146.9146 2.15432 1.4296 3.44776 1.4322h9.24c1.2934-.0026 2.5332-.5176 3.4478-1.4322s1.4296-2.1543 1.4322-3.4478v-6.62c.0131-.1228.0003-.2469-.0377-.3644s-.1002-.22563-.1828-.31746c-.0825-.09184-.1834-.16528-.2962-.21555s-.2348-.07625-.3583-.07625-.2455.02598-.3583.07625-.2137.12371-.2962.21555c-.0826.09183-.1448.19996-.1828.31746s-.0508.2416-.0377.3644v6.62c0 .8301-.3298 1.6263-.9168 2.2133-.5869.5869-1.3831.9167-2.2132.9167h-9.24c-.83013 0-1.62626-.3298-2.21324-.9167-.58699-.587-.91676-1.3832-.91676-2.2133v-9.24999c.00265-.82839.33358-1.62195.92028-2.20678.58671-.58483 1.38132-.91322 2.20972-.91322h6.62c.1228.01315.2469.00031.3644-.03767.1175-.03799.2256-.10026.3175-.18279.0918-.08253.1652-.18345.2155-.29622s.0763-.23485.0763-.35832c0-.12346-.026-.24555-.0763-.35831-.0503-.11277-.1237-.2137-.2155-.29622-.0919-.08253-.2-.14481-.3175-.18279s-.2416-.05082-.3644-.03768z" fill="#000"/></svg>
|
After Width: | Height: | Size: 2 KiB |
|
@ -2660,14 +2660,19 @@ button.ConversationDetails__action-button {
|
||||||
height: calc(#{$header-height} + var(--title-bar-drag-area-height));
|
height: calc(#{$header-height} + var(--title-bar-drag-area-height));
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
padding-left: 24px;
|
padding-left: 16px;
|
||||||
padding-right: 24px;
|
padding-right: 16px;
|
||||||
padding-top: var(--title-bar-drag-area-height);
|
padding-top: var(--title-bar-drag-area-height);
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
|
.module-left-pane--width-narrow & {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
& > * {
|
& > * {
|
||||||
margin-right: 12px;
|
margin-right: 12px;
|
||||||
|
|
||||||
|
@ -2681,6 +2686,10 @@ button.ConversationDetails__action-button {
|
||||||
|
|
||||||
&--container {
|
&--container {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
.module-left-pane--width-narrow & {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&--badged {
|
&--badged {
|
||||||
|
@ -2693,14 +2702,10 @@ button.ConversationDetails__action-button {
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.module-left-pane--width-narrow & {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__compose-icon {
|
&__compose-icon {
|
||||||
$icon: '../images/icons/v2/compose-outline-24.svg';
|
$icon: '../images/icons/v2/compose-24.svg';
|
||||||
|
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2021 Signal Messenger, LLC
|
// Copyright 2021-2022 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
@keyframes progress-animation {
|
@keyframes progress-animation {
|
||||||
|
@ -21,12 +21,12 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background: $default-background-color;
|
background: $default-background-color;
|
||||||
color: $default-text-color;
|
color: $default-text-color;
|
||||||
|
cursor: inherit;
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
|
||||||
min-height: 64px;
|
min-height: 64px;
|
||||||
padding: 12px 18px;
|
padding: 12px 18px;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
cursor: inherit;
|
width: 100%;
|
||||||
|
|
||||||
.module-left-pane--width-narrow & {
|
.module-left-pane--width-narrow & {
|
||||||
padding-left: 36px;
|
padding-left: 36px;
|
||||||
|
|
|
@ -1,31 +1,29 @@
|
||||||
// Copyright 2021 Signal Messenger, LLC
|
// Copyright 2021-2022 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
.LeftPaneSearchInput {
|
.LeftPaneSearchInput {
|
||||||
-webkit-app-region: no-drag;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
flex-grow: 1;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
|
margin: 0 16px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
&__input {
|
&__input {
|
||||||
@include font-body-2;
|
@include font-body-2;
|
||||||
@include rounded-corners;
|
|
||||||
border: none;
|
border: none;
|
||||||
|
border-radius: 8px;
|
||||||
height: 28px;
|
height: 28px;
|
||||||
padding-left: 30px;
|
padding-left: 30px;
|
||||||
padding-right: 5px;
|
padding-right: 5px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
@include light-theme {
|
@include light-theme {
|
||||||
background-color: $color-gray-05;
|
background-color: $color-gray-15;
|
||||||
|
border: solid 1px $color-gray-15;
|
||||||
color: $color-gray-90;
|
color: $color-gray-90;
|
||||||
border: solid 1px $color-gray-02;
|
|
||||||
}
|
}
|
||||||
@include dark-theme {
|
@include dark-theme {
|
||||||
|
background-color: $color-gray-65;
|
||||||
|
border: solid 1px $color-gray-65;
|
||||||
color: $color-gray-05;
|
color: $color-gray-05;
|
||||||
background-color: $color-gray-95;
|
|
||||||
border: solid 1px $color-gray-80;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&:placeholder {
|
&:placeholder {
|
||||||
|
@ -75,10 +73,10 @@
|
||||||
top: 3px;
|
top: 3px;
|
||||||
|
|
||||||
@include light-theme {
|
@include light-theme {
|
||||||
background-color: $color-gray-15;
|
background-color: $color-gray-25;
|
||||||
}
|
}
|
||||||
@include dark-theme {
|
@include dark-theme {
|
||||||
background-color: $color-gray-75;
|
background-color: $color-gray-80;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__x-button {
|
&__x-button {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2021 Signal Messenger, LLC
|
// Copyright 2021-2022 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
.module-SearchInput {
|
.module-SearchInput {
|
||||||
|
@ -12,14 +12,14 @@
|
||||||
@include font-body-2;
|
@include font-body-2;
|
||||||
|
|
||||||
@include light-theme {
|
@include light-theme {
|
||||||
background-color: $color-black-alpha-08;
|
background-color: $color-gray-15;
|
||||||
border: solid 1px $color-gray-02;
|
border: solid 1px $color-gray-15;
|
||||||
color: $color-gray-90;
|
color: $color-gray-90;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include dark-theme {
|
@include dark-theme {
|
||||||
background: $color-gray-90;
|
background-color: $color-gray-65;
|
||||||
border: solid 1px $color-gray-90;
|
border: solid 1px $color-gray-65;
|
||||||
color: $color-gray-05;
|
color: $color-gray-05;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,13 @@ const defaultConversations: Array<ConversationType> = [
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const defaultSearchProps = {
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
searchTerm: 'hello',
|
||||||
|
startSearchCounter: 0,
|
||||||
|
};
|
||||||
|
|
||||||
const defaultGroups: Array<ConversationType> = [
|
const defaultGroups: Array<ConversationType> = [
|
||||||
getDefaultConversation({
|
getDefaultConversation({
|
||||||
id: 'biking-group',
|
id: 'biking-group',
|
||||||
|
@ -72,18 +79,19 @@ const pinnedConversations: Array<ConversationType> = [
|
||||||
];
|
];
|
||||||
|
|
||||||
const defaultModeSpecificProps = {
|
const defaultModeSpecificProps = {
|
||||||
|
...defaultSearchProps,
|
||||||
mode: LeftPaneMode.Inbox as const,
|
mode: LeftPaneMode.Inbox as const,
|
||||||
pinnedConversations,
|
pinnedConversations,
|
||||||
conversations: defaultConversations,
|
conversations: defaultConversations,
|
||||||
archivedConversations: defaultArchivedConversations,
|
archivedConversations: defaultArchivedConversations,
|
||||||
isAboutToSearchInAConversation: false,
|
isAboutToSearchInAConversation: false,
|
||||||
startSearchCounter: 0,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const emptySearchResultsGroup = { isLoading: false, results: [] };
|
const emptySearchResultsGroup = { isLoading: false, results: [] };
|
||||||
|
|
||||||
const useProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({
|
const useProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({
|
||||||
cantAddContactToGroup: action('cantAddContactToGroup'),
|
cantAddContactToGroup: action('cantAddContactToGroup'),
|
||||||
|
clearConversationSearch: action('clearConversationSearch'),
|
||||||
clearGroupCreationError: action('clearGroupCreationError'),
|
clearGroupCreationError: action('clearGroupCreationError'),
|
||||||
clearSearch: action('clearSearch'),
|
clearSearch: action('clearSearch'),
|
||||||
closeCantAddContactToGroupModal: action('closeCantAddContactToGroupModal'),
|
closeCantAddContactToGroupModal: action('closeCantAddContactToGroupModal'),
|
||||||
|
@ -177,12 +185,12 @@ story.add('Inbox: no conversations', () => (
|
||||||
<LeftPane
|
<LeftPane
|
||||||
{...useProps({
|
{...useProps({
|
||||||
modeSpecificProps: {
|
modeSpecificProps: {
|
||||||
|
...defaultSearchProps,
|
||||||
mode: LeftPaneMode.Inbox,
|
mode: LeftPaneMode.Inbox,
|
||||||
pinnedConversations: [],
|
pinnedConversations: [],
|
||||||
conversations: [],
|
conversations: [],
|
||||||
archivedConversations: [],
|
archivedConversations: [],
|
||||||
isAboutToSearchInAConversation: false,
|
isAboutToSearchInAConversation: false,
|
||||||
startSearchCounter: 0,
|
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
|
@ -192,12 +200,12 @@ story.add('Inbox: only pinned conversations', () => (
|
||||||
<LeftPane
|
<LeftPane
|
||||||
{...useProps({
|
{...useProps({
|
||||||
modeSpecificProps: {
|
modeSpecificProps: {
|
||||||
|
...defaultSearchProps,
|
||||||
mode: LeftPaneMode.Inbox,
|
mode: LeftPaneMode.Inbox,
|
||||||
pinnedConversations,
|
pinnedConversations,
|
||||||
conversations: [],
|
conversations: [],
|
||||||
archivedConversations: [],
|
archivedConversations: [],
|
||||||
isAboutToSearchInAConversation: false,
|
isAboutToSearchInAConversation: false,
|
||||||
startSearchCounter: 0,
|
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
|
@ -207,12 +215,12 @@ story.add('Inbox: only non-pinned conversations', () => (
|
||||||
<LeftPane
|
<LeftPane
|
||||||
{...useProps({
|
{...useProps({
|
||||||
modeSpecificProps: {
|
modeSpecificProps: {
|
||||||
|
...defaultSearchProps,
|
||||||
mode: LeftPaneMode.Inbox,
|
mode: LeftPaneMode.Inbox,
|
||||||
pinnedConversations: [],
|
pinnedConversations: [],
|
||||||
conversations: defaultConversations,
|
conversations: defaultConversations,
|
||||||
archivedConversations: [],
|
archivedConversations: [],
|
||||||
isAboutToSearchInAConversation: false,
|
isAboutToSearchInAConversation: false,
|
||||||
startSearchCounter: 0,
|
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
|
@ -222,12 +230,12 @@ story.add('Inbox: only archived conversations', () => (
|
||||||
<LeftPane
|
<LeftPane
|
||||||
{...useProps({
|
{...useProps({
|
||||||
modeSpecificProps: {
|
modeSpecificProps: {
|
||||||
|
...defaultSearchProps,
|
||||||
mode: LeftPaneMode.Inbox,
|
mode: LeftPaneMode.Inbox,
|
||||||
pinnedConversations: [],
|
pinnedConversations: [],
|
||||||
conversations: [],
|
conversations: [],
|
||||||
archivedConversations: defaultArchivedConversations,
|
archivedConversations: defaultArchivedConversations,
|
||||||
isAboutToSearchInAConversation: false,
|
isAboutToSearchInAConversation: false,
|
||||||
startSearchCounter: 0,
|
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
|
@ -237,12 +245,12 @@ story.add('Inbox: pinned and archived conversations', () => (
|
||||||
<LeftPane
|
<LeftPane
|
||||||
{...useProps({
|
{...useProps({
|
||||||
modeSpecificProps: {
|
modeSpecificProps: {
|
||||||
|
...defaultSearchProps,
|
||||||
mode: LeftPaneMode.Inbox,
|
mode: LeftPaneMode.Inbox,
|
||||||
pinnedConversations,
|
pinnedConversations,
|
||||||
conversations: [],
|
conversations: [],
|
||||||
archivedConversations: defaultArchivedConversations,
|
archivedConversations: defaultArchivedConversations,
|
||||||
isAboutToSearchInAConversation: false,
|
isAboutToSearchInAConversation: false,
|
||||||
startSearchCounter: 0,
|
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
|
@ -252,12 +260,12 @@ story.add('Inbox: non-pinned and archived conversations', () => (
|
||||||
<LeftPane
|
<LeftPane
|
||||||
{...useProps({
|
{...useProps({
|
||||||
modeSpecificProps: {
|
modeSpecificProps: {
|
||||||
|
...defaultSearchProps,
|
||||||
mode: LeftPaneMode.Inbox,
|
mode: LeftPaneMode.Inbox,
|
||||||
pinnedConversations: [],
|
pinnedConversations: [],
|
||||||
conversations: defaultConversations,
|
conversations: defaultConversations,
|
||||||
archivedConversations: defaultArchivedConversations,
|
archivedConversations: defaultArchivedConversations,
|
||||||
isAboutToSearchInAConversation: false,
|
isAboutToSearchInAConversation: false,
|
||||||
startSearchCounter: 0,
|
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
|
@ -267,12 +275,12 @@ story.add('Inbox: pinned and non-pinned conversations', () => (
|
||||||
<LeftPane
|
<LeftPane
|
||||||
{...useProps({
|
{...useProps({
|
||||||
modeSpecificProps: {
|
modeSpecificProps: {
|
||||||
|
...defaultSearchProps,
|
||||||
mode: LeftPaneMode.Inbox,
|
mode: LeftPaneMode.Inbox,
|
||||||
pinnedConversations,
|
pinnedConversations,
|
||||||
conversations: defaultConversations,
|
conversations: defaultConversations,
|
||||||
archivedConversations: [],
|
archivedConversations: [],
|
||||||
isAboutToSearchInAConversation: false,
|
isAboutToSearchInAConversation: false,
|
||||||
startSearchCounter: 0,
|
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
|
@ -288,11 +296,11 @@ story.add('Search: no results when searching everywhere', () => (
|
||||||
<LeftPane
|
<LeftPane
|
||||||
{...useProps({
|
{...useProps({
|
||||||
modeSpecificProps: {
|
modeSpecificProps: {
|
||||||
|
...defaultSearchProps,
|
||||||
mode: LeftPaneMode.Search,
|
mode: LeftPaneMode.Search,
|
||||||
conversationResults: emptySearchResultsGroup,
|
conversationResults: emptySearchResultsGroup,
|
||||||
contactResults: emptySearchResultsGroup,
|
contactResults: emptySearchResultsGroup,
|
||||||
messageResults: emptySearchResultsGroup,
|
messageResults: emptySearchResultsGroup,
|
||||||
searchTerm: 'foo bar',
|
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
|
@ -303,11 +311,11 @@ story.add('Search: no results when searching everywhere (SMS)', () => (
|
||||||
<LeftPane
|
<LeftPane
|
||||||
{...useProps({
|
{...useProps({
|
||||||
modeSpecificProps: {
|
modeSpecificProps: {
|
||||||
|
...defaultSearchProps,
|
||||||
mode: LeftPaneMode.Search,
|
mode: LeftPaneMode.Search,
|
||||||
conversationResults: emptySearchResultsGroup,
|
conversationResults: emptySearchResultsGroup,
|
||||||
contactResults: emptySearchResultsGroup,
|
contactResults: emptySearchResultsGroup,
|
||||||
messageResults: emptySearchResultsGroup,
|
messageResults: emptySearchResultsGroup,
|
||||||
searchTerm: 'foo bar',
|
|
||||||
primarySendsSms: true,
|
primarySendsSms: true,
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
|
@ -318,12 +326,12 @@ story.add('Search: no results when searching in a conversation', () => (
|
||||||
<LeftPane
|
<LeftPane
|
||||||
{...useProps({
|
{...useProps({
|
||||||
modeSpecificProps: {
|
modeSpecificProps: {
|
||||||
|
...defaultSearchProps,
|
||||||
mode: LeftPaneMode.Search,
|
mode: LeftPaneMode.Search,
|
||||||
conversationResults: emptySearchResultsGroup,
|
conversationResults: emptySearchResultsGroup,
|
||||||
contactResults: emptySearchResultsGroup,
|
contactResults: emptySearchResultsGroup,
|
||||||
messageResults: emptySearchResultsGroup,
|
messageResults: emptySearchResultsGroup,
|
||||||
searchConversationName: 'Bing Bong',
|
searchConversationName: 'Bing Bong',
|
||||||
searchTerm: 'foo bar',
|
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
|
@ -334,11 +342,11 @@ story.add('Search: all results loading', () => (
|
||||||
<LeftPane
|
<LeftPane
|
||||||
{...useProps({
|
{...useProps({
|
||||||
modeSpecificProps: {
|
modeSpecificProps: {
|
||||||
|
...defaultSearchProps,
|
||||||
mode: LeftPaneMode.Search,
|
mode: LeftPaneMode.Search,
|
||||||
conversationResults: { isLoading: true },
|
conversationResults: { isLoading: true },
|
||||||
contactResults: { isLoading: true },
|
contactResults: { isLoading: true },
|
||||||
messageResults: { isLoading: true },
|
messageResults: { isLoading: true },
|
||||||
searchTerm: 'foo bar',
|
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
|
@ -349,6 +357,7 @@ story.add('Search: some results loading', () => (
|
||||||
<LeftPane
|
<LeftPane
|
||||||
{...useProps({
|
{...useProps({
|
||||||
modeSpecificProps: {
|
modeSpecificProps: {
|
||||||
|
...defaultSearchProps,
|
||||||
mode: LeftPaneMode.Search,
|
mode: LeftPaneMode.Search,
|
||||||
conversationResults: {
|
conversationResults: {
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
|
@ -356,7 +365,6 @@ story.add('Search: some results loading', () => (
|
||||||
},
|
},
|
||||||
contactResults: { isLoading: true },
|
contactResults: { isLoading: true },
|
||||||
messageResults: { isLoading: true },
|
messageResults: { isLoading: true },
|
||||||
searchTerm: 'foo bar',
|
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
|
@ -367,6 +375,7 @@ story.add('Search: has conversations and contacts, but not messages', () => (
|
||||||
<LeftPane
|
<LeftPane
|
||||||
{...useProps({
|
{...useProps({
|
||||||
modeSpecificProps: {
|
modeSpecificProps: {
|
||||||
|
...defaultSearchProps,
|
||||||
mode: LeftPaneMode.Search,
|
mode: LeftPaneMode.Search,
|
||||||
conversationResults: {
|
conversationResults: {
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
|
@ -374,7 +383,6 @@ 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',
|
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
|
@ -385,6 +393,7 @@ story.add('Search: all results', () => (
|
||||||
<LeftPane
|
<LeftPane
|
||||||
{...useProps({
|
{...useProps({
|
||||||
modeSpecificProps: {
|
modeSpecificProps: {
|
||||||
|
...defaultSearchProps,
|
||||||
mode: LeftPaneMode.Search,
|
mode: LeftPaneMode.Search,
|
||||||
conversationResults: {
|
conversationResults: {
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
|
@ -398,7 +407,6 @@ story.add('Search: all results', () => (
|
||||||
{ id: 'msg2', conversationId: 'bar' },
|
{ id: 'msg2', conversationId: 'bar' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
searchTerm: 'foo bar',
|
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
|
@ -614,12 +622,13 @@ story.add('Captcha dialog: required', () => (
|
||||||
<LeftPane
|
<LeftPane
|
||||||
{...useProps({
|
{...useProps({
|
||||||
modeSpecificProps: {
|
modeSpecificProps: {
|
||||||
|
...defaultSearchProps,
|
||||||
mode: LeftPaneMode.Inbox,
|
mode: LeftPaneMode.Inbox,
|
||||||
pinnedConversations,
|
pinnedConversations,
|
||||||
conversations: defaultConversations,
|
conversations: defaultConversations,
|
||||||
archivedConversations: [],
|
archivedConversations: [],
|
||||||
isAboutToSearchInAConversation: false,
|
isAboutToSearchInAConversation: false,
|
||||||
startSearchCounter: 0,
|
searchTerm: '',
|
||||||
},
|
},
|
||||||
challengeStatus: 'required',
|
challengeStatus: 'required',
|
||||||
})}
|
})}
|
||||||
|
@ -630,12 +639,13 @@ story.add('Captcha dialog: pending', () => (
|
||||||
<LeftPane
|
<LeftPane
|
||||||
{...useProps({
|
{...useProps({
|
||||||
modeSpecificProps: {
|
modeSpecificProps: {
|
||||||
|
...defaultSearchProps,
|
||||||
mode: LeftPaneMode.Inbox,
|
mode: LeftPaneMode.Inbox,
|
||||||
pinnedConversations,
|
pinnedConversations,
|
||||||
conversations: defaultConversations,
|
conversations: defaultConversations,
|
||||||
archivedConversations: [],
|
archivedConversations: [],
|
||||||
isAboutToSearchInAConversation: false,
|
isAboutToSearchInAConversation: false,
|
||||||
startSearchCounter: 0,
|
searchTerm: '',
|
||||||
},
|
},
|
||||||
challengeStatus: 'pending',
|
challengeStatus: 'pending',
|
||||||
})}
|
})}
|
||||||
|
@ -648,12 +658,13 @@ story.add('Crash report dialog', () => (
|
||||||
<LeftPane
|
<LeftPane
|
||||||
{...useProps({
|
{...useProps({
|
||||||
modeSpecificProps: {
|
modeSpecificProps: {
|
||||||
|
...defaultSearchProps,
|
||||||
mode: LeftPaneMode.Inbox,
|
mode: LeftPaneMode.Inbox,
|
||||||
pinnedConversations,
|
pinnedConversations,
|
||||||
conversations: defaultConversations,
|
conversations: defaultConversations,
|
||||||
archivedConversations: [],
|
archivedConversations: [],
|
||||||
isAboutToSearchInAConversation: false,
|
isAboutToSearchInAConversation: false,
|
||||||
startSearchCounter: 0,
|
searchTerm: '',
|
||||||
},
|
},
|
||||||
crashReportCount: 42,
|
crashReportCount: 42,
|
||||||
})}
|
})}
|
||||||
|
@ -715,3 +726,20 @@ story.add('Group Metadata: Custom Timer', () => (
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
|
|
||||||
|
story.add('Searching Conversation', () => (
|
||||||
|
<LeftPane
|
||||||
|
{...useProps({
|
||||||
|
modeSpecificProps: {
|
||||||
|
...defaultSearchProps,
|
||||||
|
mode: LeftPaneMode.Inbox,
|
||||||
|
pinnedConversations: [],
|
||||||
|
conversations: defaultConversations,
|
||||||
|
archivedConversations: [],
|
||||||
|
isAboutToSearchInAConversation: false,
|
||||||
|
searchConversation: getDefaultConversation(),
|
||||||
|
searchTerm: '',
|
||||||
|
},
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
|
|
@ -96,6 +96,7 @@ export type PropsType = {
|
||||||
|
|
||||||
// Action Creators
|
// Action Creators
|
||||||
cantAddContactToGroup: (conversationId: string) => void;
|
cantAddContactToGroup: (conversationId: string) => void;
|
||||||
|
clearConversationSearch: () => void;
|
||||||
clearGroupCreationError: () => void;
|
clearGroupCreationError: () => void;
|
||||||
clearSearch: () => void;
|
clearSearch: () => void;
|
||||||
closeCantAddContactToGroupModal: () => void;
|
closeCantAddContactToGroupModal: () => void;
|
||||||
|
@ -151,6 +152,7 @@ export const LeftPane: React.FC<PropsType> = ({
|
||||||
cantAddContactToGroup,
|
cantAddContactToGroup,
|
||||||
challengeStatus,
|
challengeStatus,
|
||||||
crashReportCount,
|
crashReportCount,
|
||||||
|
clearConversationSearch,
|
||||||
clearGroupCreationError,
|
clearGroupCreationError,
|
||||||
clearSearch,
|
clearSearch,
|
||||||
closeCantAddContactToGroupModal,
|
closeCantAddContactToGroupModal,
|
||||||
|
@ -461,7 +463,9 @@ export const LeftPane: React.FC<PropsType> = ({
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const preRowsNode = helper.getPreRowsNode({
|
const preRowsNode = helper.getPreRowsNode({
|
||||||
|
clearConversationSearch,
|
||||||
clearGroupCreationError,
|
clearGroupCreationError,
|
||||||
|
clearSearch,
|
||||||
closeCantAddContactToGroupModal,
|
closeCantAddContactToGroupModal,
|
||||||
closeMaximumGroupSizeModal,
|
closeMaximumGroupSizeModal,
|
||||||
closeRecommendedGroupSizeModal,
|
closeRecommendedGroupSizeModal,
|
||||||
|
@ -470,14 +474,11 @@ export const LeftPane: React.FC<PropsType> = ({
|
||||||
composeSaveAvatarToDisk,
|
composeSaveAvatarToDisk,
|
||||||
createGroup,
|
createGroup,
|
||||||
i18n,
|
i18n,
|
||||||
setComposeGroupAvatar,
|
|
||||||
setComposeGroupName,
|
|
||||||
setComposeGroupExpireTimer,
|
|
||||||
toggleComposeEditingAvatar,
|
|
||||||
onChangeComposeSearchTerm: event => {
|
|
||||||
setComposeSearchTerm(event.target.value);
|
|
||||||
},
|
|
||||||
removeSelectedContact: toggleConversationInChooseMembers,
|
removeSelectedContact: toggleConversationInChooseMembers,
|
||||||
|
setComposeGroupAvatar,
|
||||||
|
setComposeGroupExpireTimer,
|
||||||
|
setComposeGroupName,
|
||||||
|
toggleComposeEditingAvatar,
|
||||||
});
|
});
|
||||||
const footerContents = helper.getFooterContents({
|
const footerContents = helper.getFooterContents({
|
||||||
createGroup,
|
createGroup,
|
||||||
|
@ -550,14 +551,21 @@ export const LeftPane: React.FC<PropsType> = ({
|
||||||
{/* eslint-enable jsx-a11y/no-static-element-interactions */}
|
{/* eslint-enable jsx-a11y/no-static-element-interactions */}
|
||||||
<div className="module-left-pane__header">
|
<div className="module-left-pane__header">
|
||||||
{helper.getHeaderContents({
|
{helper.getHeaderContents({
|
||||||
clearSearch,
|
|
||||||
i18n,
|
i18n,
|
||||||
showInbox,
|
showInbox,
|
||||||
startComposing,
|
startComposing,
|
||||||
showChooseGroupMembers,
|
showChooseGroupMembers,
|
||||||
updateSearchTerm,
|
|
||||||
}) || renderMainHeader()}
|
}) || renderMainHeader()}
|
||||||
</div>
|
</div>
|
||||||
|
{helper.getSearchInput({
|
||||||
|
clearConversationSearch,
|
||||||
|
clearSearch,
|
||||||
|
i18n,
|
||||||
|
onChangeComposeSearchTerm: event => {
|
||||||
|
setComposeSearchTerm(event.target.value);
|
||||||
|
},
|
||||||
|
updateSearchTerm,
|
||||||
|
})}
|
||||||
{renderExpiredBuildDialog({ containerWidthBreakpoint: widthBreakpoint })}
|
{renderExpiredBuildDialog({ containerWidthBreakpoint: widthBreakpoint })}
|
||||||
{renderRelinkDialog({ containerWidthBreakpoint: widthBreakpoint })}
|
{renderRelinkDialog({ containerWidthBreakpoint: widthBreakpoint })}
|
||||||
{renderNetworkStatus({ containerWidthBreakpoint: widthBreakpoint })}
|
{renderNetworkStatus({ containerWidthBreakpoint: widthBreakpoint })}
|
||||||
|
|
92
ts/components/LeftPaneMainSearchInput.tsx
Normal file
92
ts/components/LeftPaneMainSearchInput.tsx
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
// Copyright 2022 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
import React, { useEffect, useRef } from 'react';
|
||||||
|
|
||||||
|
import type { LocalizerType } from '../types/Util';
|
||||||
|
import type { ConversationType } from '../state/ducks/conversations';
|
||||||
|
import { LeftPaneSearchInput } from './LeftPaneSearchInput';
|
||||||
|
import { usePrevious } from '../hooks/usePrevious';
|
||||||
|
|
||||||
|
export type PropsType = {
|
||||||
|
clearConversationSearch: () => void;
|
||||||
|
clearSearch: () => void;
|
||||||
|
disabled?: boolean;
|
||||||
|
i18n: LocalizerType;
|
||||||
|
searchConversation: undefined | ConversationType;
|
||||||
|
searchTerm: string;
|
||||||
|
startSearchCounter: number;
|
||||||
|
updateSearchTerm: (searchTerm: string) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const LeftPaneMainSearchInput = ({
|
||||||
|
clearConversationSearch,
|
||||||
|
clearSearch,
|
||||||
|
disabled,
|
||||||
|
i18n,
|
||||||
|
searchConversation,
|
||||||
|
searchTerm,
|
||||||
|
startSearchCounter,
|
||||||
|
updateSearchTerm,
|
||||||
|
}: PropsType): JSX.Element => {
|
||||||
|
const inputRef = useRef<HTMLInputElement | null>(null);
|
||||||
|
|
||||||
|
const prevSearchConversationId = usePrevious(
|
||||||
|
undefined,
|
||||||
|
searchConversation?.id
|
||||||
|
);
|
||||||
|
const prevSearchCounter = usePrevious(startSearchCounter, startSearchCounter);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// When user chooses to search in a given conversation we focus the field for them
|
||||||
|
if (
|
||||||
|
searchConversation &&
|
||||||
|
searchConversation.id !== prevSearchConversationId
|
||||||
|
) {
|
||||||
|
inputRef.current?.focus();
|
||||||
|
}
|
||||||
|
// When user chooses to start a new search, we focus the field
|
||||||
|
if (startSearchCounter !== prevSearchCounter) {
|
||||||
|
inputRef.current?.select();
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
prevSearchConversationId,
|
||||||
|
prevSearchCounter,
|
||||||
|
searchConversation,
|
||||||
|
startSearchCounter,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<LeftPaneSearchInput
|
||||||
|
disabled={disabled}
|
||||||
|
i18n={i18n}
|
||||||
|
onBlur={() => {
|
||||||
|
if (!searchConversation && !searchTerm) {
|
||||||
|
clearSearch();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onChangeValue={nextSearchTerm => {
|
||||||
|
if (!nextSearchTerm) {
|
||||||
|
if (searchConversation) {
|
||||||
|
clearConversationSearch();
|
||||||
|
} else {
|
||||||
|
clearSearch();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateSearchTerm) {
|
||||||
|
updateSearchTerm(nextSearchTerm);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onClear={() => {
|
||||||
|
clearSearch();
|
||||||
|
inputRef.current?.focus();
|
||||||
|
}}
|
||||||
|
ref={inputRef}
|
||||||
|
searchConversation={searchConversation}
|
||||||
|
value={searchTerm}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2021 Signal Messenger, LLC
|
// Copyright 2021-2022 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
@ -10,7 +10,6 @@ import { setupI18n } from '../util/setupI18n';
|
||||||
import enMessages from '../../_locales/en/messages.json';
|
import enMessages from '../../_locales/en/messages.json';
|
||||||
import type { PropsType } from './MainHeader';
|
import type { PropsType } from './MainHeader';
|
||||||
import { MainHeader } from './MainHeader';
|
import { MainHeader } from './MainHeader';
|
||||||
import { getDefaultConversation } from '../test-both/helpers/getDefaultConversation';
|
|
||||||
import { ThemeType } from '../types/Util';
|
import { ThemeType } from '../types/Util';
|
||||||
|
|
||||||
const i18n = setupI18n('en', enMessages);
|
const i18n = setupI18n('en', enMessages);
|
||||||
|
@ -23,10 +22,6 @@ const optionalText = (name: string, value: string | undefined) =>
|
||||||
text(name, value || '') || undefined;
|
text(name, value || '') || undefined;
|
||||||
|
|
||||||
const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({
|
const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({
|
||||||
searchTerm: requiredText('searchTerm', overrideProps.searchTerm),
|
|
||||||
searchConversation: overrideProps.searchConversation,
|
|
||||||
selectedConversation: undefined,
|
|
||||||
startSearchCounter: 0,
|
|
||||||
theme: ThemeType.light,
|
theme: ThemeType.light,
|
||||||
|
|
||||||
phoneNumber: optionalText('phoneNumber', overrideProps.phoneNumber),
|
phoneNumber: optionalText('phoneNumber', overrideProps.phoneNumber),
|
||||||
|
@ -37,9 +32,6 @@ const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({
|
||||||
|
|
||||||
i18n,
|
i18n,
|
||||||
|
|
||||||
updateSearchTerm: action('updateSearchTerm'),
|
|
||||||
clearConversationSearch: action('clearConversationSearch'),
|
|
||||||
clearSearch: action('clearSearch'),
|
|
||||||
startUpdate: action('startUpdate'),
|
startUpdate: action('startUpdate'),
|
||||||
|
|
||||||
showArchivedConversations: action('showArchivedConversations'),
|
showArchivedConversations: action('showArchivedConversations'),
|
||||||
|
@ -71,35 +63,6 @@ story.add('Phone Number', () => {
|
||||||
return <MainHeader {...props} />;
|
return <MainHeader {...props} />;
|
||||||
});
|
});
|
||||||
|
|
||||||
story.add('Search Term', () => {
|
|
||||||
const props = createProps({
|
|
||||||
name: 'John Smith',
|
|
||||||
searchTerm: 'Hewwo?',
|
|
||||||
title: 'John Smith',
|
|
||||||
});
|
|
||||||
|
|
||||||
return <MainHeader {...props} />;
|
|
||||||
});
|
|
||||||
|
|
||||||
story.add('Searching Conversation', () => {
|
|
||||||
const props = createProps({
|
|
||||||
name: 'John Smith',
|
|
||||||
searchConversation: getDefaultConversation(),
|
|
||||||
});
|
|
||||||
|
|
||||||
return <MainHeader {...props} />;
|
|
||||||
});
|
|
||||||
|
|
||||||
story.add('Searching Conversation with Term', () => {
|
|
||||||
const props = createProps({
|
|
||||||
name: 'John Smith',
|
|
||||||
searchTerm: 'address',
|
|
||||||
searchConversation: getDefaultConversation(),
|
|
||||||
});
|
|
||||||
|
|
||||||
return <MainHeader {...props} />;
|
|
||||||
});
|
|
||||||
|
|
||||||
story.add('Update Available', () => {
|
story.add('Update Available', () => {
|
||||||
const props = createProps({ hasPendingUpdate: true });
|
const props = createProps({ hasPendingUpdate: true });
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2018-2021 Signal Messenger, LLC
|
// Copyright 2018-2022 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
@ -10,39 +10,25 @@ import { Avatar } from './Avatar';
|
||||||
import { AvatarPopup } from './AvatarPopup';
|
import { AvatarPopup } from './AvatarPopup';
|
||||||
import type { LocalizerType, ThemeType } from '../types/Util';
|
import type { LocalizerType, ThemeType } from '../types/Util';
|
||||||
import type { AvatarColorType } from '../types/Colors';
|
import type { AvatarColorType } from '../types/Colors';
|
||||||
import type { ConversationType } from '../state/ducks/conversations';
|
|
||||||
import { LeftPaneSearchInput } from './LeftPaneSearchInput';
|
|
||||||
import type { BadgeType } from '../badges/types';
|
import type { BadgeType } from '../badges/types';
|
||||||
|
|
||||||
export type PropsType = {
|
export type PropsType = {
|
||||||
searchTerm: string;
|
|
||||||
searchConversation: undefined | ConversationType;
|
|
||||||
startSearchCounter: number;
|
|
||||||
selectedConversation: undefined | ConversationType;
|
|
||||||
|
|
||||||
// For display
|
|
||||||
phoneNumber?: string;
|
|
||||||
isMe?: boolean;
|
|
||||||
name?: string;
|
|
||||||
color?: AvatarColorType;
|
|
||||||
disabled?: boolean;
|
|
||||||
isVerified?: boolean;
|
|
||||||
profileName?: string;
|
|
||||||
title: string;
|
|
||||||
avatarPath?: string;
|
avatarPath?: string;
|
||||||
badge?: BadgeType;
|
badge?: BadgeType;
|
||||||
|
color?: AvatarColorType;
|
||||||
hasPendingUpdate: boolean;
|
hasPendingUpdate: boolean;
|
||||||
theme: ThemeType;
|
|
||||||
|
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
|
isMe?: boolean;
|
||||||
updateSearchTerm: (searchTerm: string) => void;
|
isVerified?: boolean;
|
||||||
startUpdate: () => unknown;
|
name?: string;
|
||||||
clearConversationSearch: () => void;
|
phoneNumber?: string;
|
||||||
clearSearch: () => void;
|
profileName?: string;
|
||||||
|
theme: ThemeType;
|
||||||
|
title: string;
|
||||||
|
|
||||||
showArchivedConversations: () => void;
|
showArchivedConversations: () => void;
|
||||||
startComposing: () => void;
|
startComposing: () => void;
|
||||||
|
startUpdate: () => unknown;
|
||||||
toggleProfileEditor: () => void;
|
toggleProfileEditor: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -52,35 +38,15 @@ type StateType = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export class MainHeader extends React.Component<PropsType, StateType> {
|
export class MainHeader extends React.Component<PropsType, StateType> {
|
||||||
private readonly inputRef: React.RefObject<HTMLInputElement>;
|
|
||||||
|
|
||||||
constructor(props: PropsType) {
|
constructor(props: PropsType) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.inputRef = React.createRef();
|
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
showingAvatarPopup: false,
|
showingAvatarPopup: false,
|
||||||
popperRoot: null,
|
popperRoot: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public override componentDidUpdate(prevProps: PropsType): void {
|
|
||||||
const { searchConversation, startSearchCounter } = this.props;
|
|
||||||
|
|
||||||
// When user chooses to search in a given conversation we focus the field for them
|
|
||||||
if (
|
|
||||||
searchConversation &&
|
|
||||||
searchConversation.id !== prevProps.searchConversation?.id
|
|
||||||
) {
|
|
||||||
this.setFocus();
|
|
||||||
}
|
|
||||||
// When user chooses to start a new search, we focus the field
|
|
||||||
if (startSearchCounter !== prevProps.startSearchCounter) {
|
|
||||||
this.setSelected();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public handleOutsideClick = ({ target }: MouseEvent): void => {
|
public handleOutsideClick = ({ target }: MouseEvent): void => {
|
||||||
const { popperRoot, showingAvatarPopup } = this.state;
|
const { popperRoot, showingAvatarPopup } = this.state;
|
||||||
|
|
||||||
|
@ -134,42 +100,6 @@ export class MainHeader extends React.Component<PropsType, StateType> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateSearch = (searchTerm: string): void => {
|
|
||||||
const {
|
|
||||||
updateSearchTerm,
|
|
||||||
clearConversationSearch,
|
|
||||||
clearSearch,
|
|
||||||
searchConversation,
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
if (!searchTerm) {
|
|
||||||
if (searchConversation) {
|
|
||||||
clearConversationSearch();
|
|
||||||
} else {
|
|
||||||
clearSearch();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (updateSearchTerm) {
|
|
||||||
updateSearchTerm(searchTerm);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public clearSearch = (): void => {
|
|
||||||
const { clearSearch } = this.props;
|
|
||||||
clearSearch();
|
|
||||||
this.setFocus();
|
|
||||||
};
|
|
||||||
|
|
||||||
private handleInputBlur = (): void => {
|
|
||||||
const { clearSearch, searchConversation, searchTerm } = this.props;
|
|
||||||
if (!searchConversation && !searchTerm) {
|
|
||||||
clearSearch();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public handleGlobalKeyDown = (event: KeyboardEvent): void => {
|
public handleGlobalKeyDown = (event: KeyboardEvent): void => {
|
||||||
const { showingAvatarPopup } = this.state;
|
const { showingAvatarPopup } = this.state;
|
||||||
const { key } = event;
|
const { key } = event;
|
||||||
|
@ -179,31 +109,16 @@ export class MainHeader extends React.Component<PropsType, StateType> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public setFocus = (): void => {
|
|
||||||
if (this.inputRef.current) {
|
|
||||||
this.inputRef.current.focus();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public setSelected = (): void => {
|
|
||||||
if (this.inputRef.current) {
|
|
||||||
this.inputRef.current.select();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public override render(): JSX.Element {
|
public override render(): JSX.Element {
|
||||||
const {
|
const {
|
||||||
avatarPath,
|
avatarPath,
|
||||||
badge,
|
badge,
|
||||||
color,
|
color,
|
||||||
disabled,
|
|
||||||
hasPendingUpdate,
|
hasPendingUpdate,
|
||||||
i18n,
|
i18n,
|
||||||
name,
|
name,
|
||||||
phoneNumber,
|
phoneNumber,
|
||||||
profileName,
|
profileName,
|
||||||
searchConversation,
|
|
||||||
searchTerm,
|
|
||||||
showArchivedConversations,
|
showArchivedConversations,
|
||||||
startComposing,
|
startComposing,
|
||||||
startUpdate,
|
startUpdate,
|
||||||
|
@ -213,8 +128,6 @@ export class MainHeader extends React.Component<PropsType, StateType> {
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const { showingAvatarPopup, popperRoot } = this.state;
|
const { showingAvatarPopup, popperRoot } = this.state;
|
||||||
|
|
||||||
const isSearching = Boolean(searchConversation || searchTerm.trim().length);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="module-main-header">
|
<div className="module-main-header">
|
||||||
<Manager>
|
<Manager>
|
||||||
|
@ -291,25 +204,13 @@ export class MainHeader extends React.Component<PropsType, StateType> {
|
||||||
)
|
)
|
||||||
: null}
|
: null}
|
||||||
</Manager>
|
</Manager>
|
||||||
<LeftPaneSearchInput
|
<button
|
||||||
disabled={disabled}
|
aria-label={i18n('newConversation')}
|
||||||
i18n={i18n}
|
className="module-main-header__compose-icon"
|
||||||
onBlur={this.handleInputBlur}
|
onClick={startComposing}
|
||||||
onChangeValue={this.updateSearch}
|
title={i18n('newConversation')}
|
||||||
onClear={this.clearSearch}
|
type="button"
|
||||||
ref={this.inputRef}
|
|
||||||
searchConversation={searchConversation}
|
|
||||||
value={searchTerm}
|
|
||||||
/>
|
/>
|
||||||
{!isSearching && (
|
|
||||||
<button
|
|
||||||
aria-label={i18n('newConversation')}
|
|
||||||
className="module-main-header__compose-icon"
|
|
||||||
onClick={startComposing}
|
|
||||||
title={i18n('newConversation')}
|
|
||||||
type="button"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,15 +49,11 @@ export class LeftPaneArchiveHelper extends LeftPaneHelper<LeftPaneArchivePropsTy
|
||||||
}
|
}
|
||||||
|
|
||||||
override getHeaderContents({
|
override getHeaderContents({
|
||||||
clearSearch,
|
|
||||||
i18n,
|
i18n,
|
||||||
showInbox,
|
showInbox,
|
||||||
updateSearchTerm,
|
|
||||||
}: Readonly<{
|
}: Readonly<{
|
||||||
clearSearch: () => void;
|
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
showInbox: () => void;
|
showInbox: () => void;
|
||||||
updateSearchTerm: (query: string) => void;
|
|
||||||
}>): ReactChild {
|
}>): ReactChild {
|
||||||
return (
|
return (
|
||||||
<div className="module-left-pane__header__contents">
|
<div className="module-left-pane__header__contents">
|
||||||
|
@ -69,29 +65,44 @@ export class LeftPaneArchiveHelper extends LeftPaneHelper<LeftPaneArchivePropsTy
|
||||||
type="button"
|
type="button"
|
||||||
/>
|
/>
|
||||||
<div className="module-left-pane__header__contents__text">
|
<div className="module-left-pane__header__contents__text">
|
||||||
{this.searchConversation ? (
|
{i18n('archivedConversations')}
|
||||||
<LeftPaneSearchInput
|
|
||||||
i18n={i18n}
|
|
||||||
onChangeValue={newValue => {
|
|
||||||
updateSearchTerm(newValue);
|
|
||||||
}}
|
|
||||||
onClear={() => {
|
|
||||||
clearSearch();
|
|
||||||
}}
|
|
||||||
ref={el => {
|
|
||||||
el?.focus();
|
|
||||||
}}
|
|
||||||
searchConversation={this.searchConversation}
|
|
||||||
value={this.searchTerm}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
i18n('archivedConversations')
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override getSearchInput({
|
||||||
|
clearSearch,
|
||||||
|
i18n,
|
||||||
|
updateSearchTerm,
|
||||||
|
}: Readonly<{
|
||||||
|
clearConversationSearch: () => unknown;
|
||||||
|
clearSearch: () => unknown;
|
||||||
|
i18n: LocalizerType;
|
||||||
|
updateSearchTerm: (searchTerm: string) => unknown;
|
||||||
|
}>): ReactChild | null {
|
||||||
|
if (!this.searchConversation) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<LeftPaneSearchInput
|
||||||
|
i18n={i18n}
|
||||||
|
onChangeValue={newValue => {
|
||||||
|
updateSearchTerm(newValue);
|
||||||
|
}}
|
||||||
|
onClear={() => {
|
||||||
|
clearSearch();
|
||||||
|
}}
|
||||||
|
ref={el => {
|
||||||
|
el?.focus();
|
||||||
|
}}
|
||||||
|
searchConversation={this.searchConversation}
|
||||||
|
value={this.searchTerm}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
override getBackAction({ showInbox }: { showInbox: () => void }): () => void {
|
override getBackAction({ showInbox }: { showInbox: () => void }): () => void {
|
||||||
return showInbox;
|
return showInbox;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2021 Signal Messenger, LLC
|
// Copyright 2021-2022 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import type { ReactChild, ChangeEvent } from 'react';
|
import type { ReactChild, ChangeEvent } from 'react';
|
||||||
|
@ -105,21 +105,37 @@ export class LeftPaneChooseGroupMembersHelper extends LeftPaneHelper<LeftPaneCho
|
||||||
return startComposing;
|
return startComposing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override getSearchInput({
|
||||||
|
i18n,
|
||||||
|
onChangeComposeSearchTerm,
|
||||||
|
}: Readonly<{
|
||||||
|
i18n: LocalizerType;
|
||||||
|
onChangeComposeSearchTerm: (
|
||||||
|
event: ChangeEvent<HTMLInputElement>
|
||||||
|
) => unknown;
|
||||||
|
}>): ReactChild {
|
||||||
|
return (
|
||||||
|
<SearchInput
|
||||||
|
moduleClassName="module-left-pane__compose-search-form"
|
||||||
|
onChange={onChangeComposeSearchTerm}
|
||||||
|
placeholder={i18n('contactSearchPlaceholder')}
|
||||||
|
ref={focusRef}
|
||||||
|
value={this.searchTerm}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
override getPreRowsNode({
|
override getPreRowsNode({
|
||||||
closeCantAddContactToGroupModal,
|
closeCantAddContactToGroupModal,
|
||||||
closeMaximumGroupSizeModal,
|
closeMaximumGroupSizeModal,
|
||||||
closeRecommendedGroupSizeModal,
|
closeRecommendedGroupSizeModal,
|
||||||
i18n,
|
i18n,
|
||||||
onChangeComposeSearchTerm,
|
|
||||||
removeSelectedContact,
|
removeSelectedContact,
|
||||||
}: Readonly<{
|
}: Readonly<{
|
||||||
closeCantAddContactToGroupModal: () => unknown;
|
closeCantAddContactToGroupModal: () => unknown;
|
||||||
closeMaximumGroupSizeModal: () => unknown;
|
closeMaximumGroupSizeModal: () => unknown;
|
||||||
closeRecommendedGroupSizeModal: () => unknown;
|
closeRecommendedGroupSizeModal: () => unknown;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
onChangeComposeSearchTerm: (
|
|
||||||
event: ChangeEvent<HTMLInputElement>
|
|
||||||
) => unknown;
|
|
||||||
removeSelectedContact: (conversationId: string) => unknown;
|
removeSelectedContact: (conversationId: string) => unknown;
|
||||||
}>): ReactChild {
|
}>): ReactChild {
|
||||||
let modalNode: undefined | ReactChild;
|
let modalNode: undefined | ReactChild;
|
||||||
|
@ -154,14 +170,6 @@ export class LeftPaneChooseGroupMembersHelper extends LeftPaneHelper<LeftPaneCho
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SearchInput
|
|
||||||
moduleClassName="module-left-pane__compose-search-form"
|
|
||||||
onChange={onChangeComposeSearchTerm}
|
|
||||||
placeholder={i18n('contactSearchPlaceholder')}
|
|
||||||
ref={focusRef}
|
|
||||||
value={this.searchTerm}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{Boolean(this.selectedContacts.length) && (
|
{Boolean(this.selectedContacts.length) && (
|
||||||
<ContactPills>
|
<ContactPills>
|
||||||
{this.selectedContacts.map(contact => (
|
{this.selectedContacts.map(contact => (
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2021 Signal Messenger, LLC
|
// Copyright 2021-2022 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import type { ReactChild, ChangeEvent } from 'react';
|
import type { ReactChild, ChangeEvent } from 'react';
|
||||||
|
@ -94,7 +94,7 @@ export class LeftPaneComposeHelper extends LeftPaneHelper<LeftPaneComposePropsTy
|
||||||
return showInbox;
|
return showInbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
override getPreRowsNode({
|
override getSearchInput({
|
||||||
i18n,
|
i18n,
|
||||||
onChangeComposeSearchTerm,
|
onChangeComposeSearchTerm,
|
||||||
}: Readonly<{
|
}: Readonly<{
|
||||||
|
@ -104,21 +104,25 @@ export class LeftPaneComposeHelper extends LeftPaneHelper<LeftPaneComposePropsTy
|
||||||
) => unknown;
|
) => unknown;
|
||||||
}>): ReactChild {
|
}>): ReactChild {
|
||||||
return (
|
return (
|
||||||
<>
|
<SearchInput
|
||||||
<SearchInput
|
moduleClassName="module-left-pane__compose-search-form"
|
||||||
moduleClassName="module-left-pane__compose-search-form"
|
onChange={onChangeComposeSearchTerm}
|
||||||
onChange={onChangeComposeSearchTerm}
|
placeholder={i18n('contactSearchPlaceholder')}
|
||||||
placeholder={i18n('contactSearchPlaceholder')}
|
ref={focusRef}
|
||||||
ref={focusRef}
|
value={this.searchTerm}
|
||||||
value={this.searchTerm}
|
/>
|
||||||
/>
|
);
|
||||||
|
}
|
||||||
|
|
||||||
{this.getRowCount() ? null : (
|
override getPreRowsNode({
|
||||||
<div className="module-left-pane__compose-no-contacts">
|
i18n,
|
||||||
{i18n('noConversationsFound')}
|
}: Readonly<{
|
||||||
</div>
|
i18n: LocalizerType;
|
||||||
)}
|
}>): ReactChild | null {
|
||||||
</>
|
return this.getRowCount() ? null : (
|
||||||
|
<div className="module-left-pane__compose-no-contacts">
|
||||||
|
{i18n('noConversationsFound')}
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2021 Signal Messenger, LLC
|
// Copyright 2021-2022 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import type { ChangeEvent, ReactChild } from 'react';
|
import type { ChangeEvent, ReactChild } from 'react';
|
||||||
|
@ -24,12 +24,24 @@ export type ToFindType = {
|
||||||
export abstract class LeftPaneHelper<T> {
|
export abstract class LeftPaneHelper<T> {
|
||||||
getHeaderContents(
|
getHeaderContents(
|
||||||
_: Readonly<{
|
_: Readonly<{
|
||||||
clearSearch: () => void;
|
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
showInbox: () => void;
|
showInbox: () => void;
|
||||||
startComposing: () => void;
|
startComposing: () => void;
|
||||||
showChooseGroupMembers: () => void;
|
showChooseGroupMembers: () => void;
|
||||||
updateSearchTerm: (query: string) => void;
|
}>
|
||||||
|
): null | ReactChild {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
getSearchInput(
|
||||||
|
_: Readonly<{
|
||||||
|
clearConversationSearch: () => unknown;
|
||||||
|
clearSearch: () => unknown;
|
||||||
|
i18n: LocalizerType;
|
||||||
|
onChangeComposeSearchTerm: (
|
||||||
|
event: ChangeEvent<HTMLInputElement>
|
||||||
|
) => unknown;
|
||||||
|
updateSearchTerm: (searchTerm: string) => unknown;
|
||||||
}>
|
}>
|
||||||
): null | ReactChild {
|
): null | ReactChild {
|
||||||
return null;
|
return null;
|
||||||
|
@ -47,7 +59,9 @@ export abstract class LeftPaneHelper<T> {
|
||||||
|
|
||||||
getPreRowsNode(
|
getPreRowsNode(
|
||||||
_: Readonly<{
|
_: Readonly<{
|
||||||
|
clearConversationSearch: () => unknown;
|
||||||
clearGroupCreationError: () => void;
|
clearGroupCreationError: () => void;
|
||||||
|
clearSearch: () => unknown;
|
||||||
closeCantAddContactToGroupModal: () => unknown;
|
closeCantAddContactToGroupModal: () => unknown;
|
||||||
closeMaximumGroupSizeModal: () => unknown;
|
closeMaximumGroupSizeModal: () => unknown;
|
||||||
closeRecommendedGroupSizeModal: () => unknown;
|
closeRecommendedGroupSizeModal: () => unknown;
|
||||||
|
@ -56,13 +70,10 @@ export abstract class LeftPaneHelper<T> {
|
||||||
composeSaveAvatarToDisk: SaveAvatarToDiskActionType;
|
composeSaveAvatarToDisk: SaveAvatarToDiskActionType;
|
||||||
createGroup: () => unknown;
|
createGroup: () => unknown;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
setComposeGroupAvatar: (_: undefined | Uint8Array) => unknown;
|
|
||||||
setComposeGroupName: (_: string) => unknown;
|
|
||||||
setComposeGroupExpireTimer: (_: number) => void;
|
|
||||||
onChangeComposeSearchTerm: (
|
|
||||||
event: ChangeEvent<HTMLInputElement>
|
|
||||||
) => unknown;
|
|
||||||
removeSelectedContact: (_: string) => unknown;
|
removeSelectedContact: (_: string) => unknown;
|
||||||
|
setComposeGroupAvatar: (_: undefined | Uint8Array) => unknown;
|
||||||
|
setComposeGroupExpireTimer: (_: number) => void;
|
||||||
|
setComposeGroupName: (_: string) => unknown;
|
||||||
toggleComposeEditingAvatar: () => unknown;
|
toggleComposeEditingAvatar: () => unknown;
|
||||||
}>
|
}>
|
||||||
): null | ReactChild {
|
): null | ReactChild {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2021 Signal Messenger, LLC
|
// Copyright 2021-2022 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import { last } from 'lodash';
|
import { last } from 'lodash';
|
||||||
|
@ -7,6 +7,7 @@ import React from 'react';
|
||||||
|
|
||||||
import { Intl } from '../Intl';
|
import { Intl } from '../Intl';
|
||||||
import type { ToFindType } from './LeftPaneHelper';
|
import type { ToFindType } from './LeftPaneHelper';
|
||||||
|
import type { ConversationType } from '../../state/ducks/conversations';
|
||||||
import { LeftPaneHelper } from './LeftPaneHelper';
|
import { LeftPaneHelper } from './LeftPaneHelper';
|
||||||
import { getConversationInDirection } from './getConversationInDirection';
|
import { getConversationInDirection } from './getConversationInDirection';
|
||||||
import type { Row } from '../ConversationList';
|
import type { Row } from '../ConversationList';
|
||||||
|
@ -14,6 +15,7 @@ import { RowType } from '../ConversationList';
|
||||||
import type { PropsData as ConversationListItemPropsType } from '../conversationList/ConversationListItem';
|
import type { PropsData as ConversationListItemPropsType } from '../conversationList/ConversationListItem';
|
||||||
import type { LocalizerType } from '../../types/Util';
|
import type { LocalizerType } from '../../types/Util';
|
||||||
import { handleKeydownForSearch } from './handleKeydownForSearch';
|
import { handleKeydownForSearch } from './handleKeydownForSearch';
|
||||||
|
import { LeftPaneMainSearchInput } from '../LeftPaneMainSearchInput';
|
||||||
|
|
||||||
export type LeftPaneInboxPropsType = {
|
export type LeftPaneInboxPropsType = {
|
||||||
conversations: ReadonlyArray<ConversationListItemPropsType>;
|
conversations: ReadonlyArray<ConversationListItemPropsType>;
|
||||||
|
@ -21,6 +23,9 @@ export type LeftPaneInboxPropsType = {
|
||||||
pinnedConversations: ReadonlyArray<ConversationListItemPropsType>;
|
pinnedConversations: ReadonlyArray<ConversationListItemPropsType>;
|
||||||
isAboutToSearchInAConversation: boolean;
|
isAboutToSearchInAConversation: boolean;
|
||||||
startSearchCounter: number;
|
startSearchCounter: number;
|
||||||
|
searchDisabled: boolean;
|
||||||
|
searchTerm: string;
|
||||||
|
searchConversation: undefined | ConversationType;
|
||||||
};
|
};
|
||||||
|
|
||||||
export class LeftPaneInboxHelper extends LeftPaneHelper<LeftPaneInboxPropsType> {
|
export class LeftPaneInboxHelper extends LeftPaneHelper<LeftPaneInboxPropsType> {
|
||||||
|
@ -34,12 +39,21 @@ export class LeftPaneInboxHelper extends LeftPaneHelper<LeftPaneInboxPropsType>
|
||||||
|
|
||||||
private readonly startSearchCounter: number;
|
private readonly startSearchCounter: number;
|
||||||
|
|
||||||
|
private readonly searchDisabled: boolean;
|
||||||
|
|
||||||
|
private readonly searchTerm: string;
|
||||||
|
|
||||||
|
private readonly searchConversation: undefined | ConversationType;
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
conversations,
|
conversations,
|
||||||
archivedConversations,
|
archivedConversations,
|
||||||
pinnedConversations,
|
pinnedConversations,
|
||||||
isAboutToSearchInAConversation,
|
isAboutToSearchInAConversation,
|
||||||
startSearchCounter,
|
startSearchCounter,
|
||||||
|
searchDisabled,
|
||||||
|
searchTerm,
|
||||||
|
searchConversation,
|
||||||
}: Readonly<LeftPaneInboxPropsType>) {
|
}: Readonly<LeftPaneInboxPropsType>) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
@ -48,6 +62,9 @@ export class LeftPaneInboxHelper extends LeftPaneHelper<LeftPaneInboxPropsType>
|
||||||
this.pinnedConversations = pinnedConversations;
|
this.pinnedConversations = pinnedConversations;
|
||||||
this.isAboutToSearchInAConversation = isAboutToSearchInAConversation;
|
this.isAboutToSearchInAConversation = isAboutToSearchInAConversation;
|
||||||
this.startSearchCounter = startSearchCounter;
|
this.startSearchCounter = startSearchCounter;
|
||||||
|
this.searchDisabled = searchDisabled;
|
||||||
|
this.searchTerm = searchTerm;
|
||||||
|
this.searchConversation = searchConversation;
|
||||||
}
|
}
|
||||||
|
|
||||||
getRowCount(): number {
|
getRowCount(): number {
|
||||||
|
@ -61,9 +78,36 @@ export class LeftPaneInboxHelper extends LeftPaneHelper<LeftPaneInboxPropsType>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override getSearchInput({
|
||||||
|
clearConversationSearch,
|
||||||
|
clearSearch,
|
||||||
|
i18n,
|
||||||
|
updateSearchTerm,
|
||||||
|
}: Readonly<{
|
||||||
|
clearConversationSearch: () => unknown;
|
||||||
|
clearSearch: () => unknown;
|
||||||
|
i18n: LocalizerType;
|
||||||
|
updateSearchTerm: (searchTerm: string) => unknown;
|
||||||
|
}>): ReactChild {
|
||||||
|
return (
|
||||||
|
<LeftPaneMainSearchInput
|
||||||
|
clearConversationSearch={clearConversationSearch}
|
||||||
|
clearSearch={clearSearch}
|
||||||
|
disabled={this.searchDisabled}
|
||||||
|
i18n={i18n}
|
||||||
|
searchConversation={this.searchConversation}
|
||||||
|
searchTerm={this.searchTerm}
|
||||||
|
startSearchCounter={this.startSearchCounter}
|
||||||
|
updateSearchTerm={updateSearchTerm}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
override getPreRowsNode({
|
override getPreRowsNode({
|
||||||
i18n,
|
i18n,
|
||||||
}: Readonly<{ i18n: LocalizerType }>): null | ReactChild {
|
}: Readonly<{
|
||||||
|
i18n: LocalizerType;
|
||||||
|
}>): ReactChild | null {
|
||||||
if (this.getRowCount() === 0) {
|
if (this.getRowCount() === 0) {
|
||||||
return (
|
return (
|
||||||
<div className="module-left-pane__empty">
|
<div className="module-left-pane__empty">
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2021 Signal Messenger, LLC
|
// Copyright 2021-2022 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import type { ReactChild } from 'react';
|
import type { ReactChild } from 'react';
|
||||||
|
@ -11,6 +11,8 @@ import type { Row } from '../ConversationList';
|
||||||
import { RowType } from '../ConversationList';
|
import { RowType } from '../ConversationList';
|
||||||
import type { PropsData as ConversationListItemPropsType } from '../conversationList/ConversationListItem';
|
import type { PropsData as ConversationListItemPropsType } from '../conversationList/ConversationListItem';
|
||||||
import { handleKeydownForSearch } from './handleKeydownForSearch';
|
import { handleKeydownForSearch } from './handleKeydownForSearch';
|
||||||
|
import type { ConversationType } from '../../state/ducks/conversations';
|
||||||
|
import { LeftPaneMainSearchInput } from '../LeftPaneMainSearchInput';
|
||||||
|
|
||||||
import { Intl } from '../Intl';
|
import { Intl } from '../Intl';
|
||||||
import { Emojify } from '../conversation/Emojify';
|
import { Emojify } from '../conversation/Emojify';
|
||||||
|
@ -37,6 +39,9 @@ export type LeftPaneSearchPropsType = {
|
||||||
searchConversationName?: string;
|
searchConversationName?: string;
|
||||||
primarySendsSms: boolean;
|
primarySendsSms: boolean;
|
||||||
searchTerm: string;
|
searchTerm: string;
|
||||||
|
startSearchCounter: number;
|
||||||
|
searchDisabled: boolean;
|
||||||
|
searchConversation: undefined | ConversationType;
|
||||||
};
|
};
|
||||||
|
|
||||||
const searchResultKeys: Array<
|
const searchResultKeys: Array<
|
||||||
|
@ -61,30 +66,70 @@ export class LeftPaneSearchHelper extends LeftPaneHelper<LeftPaneSearchPropsType
|
||||||
|
|
||||||
private readonly searchTerm: string;
|
private readonly searchTerm: string;
|
||||||
|
|
||||||
|
private readonly startSearchCounter: number;
|
||||||
|
|
||||||
|
private readonly searchDisabled: boolean;
|
||||||
|
|
||||||
|
private readonly searchConversation: undefined | ConversationType;
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
conversationResults,
|
|
||||||
contactResults,
|
contactResults,
|
||||||
|
conversationResults,
|
||||||
messageResults,
|
messageResults,
|
||||||
searchConversationName,
|
|
||||||
primarySendsSms,
|
primarySendsSms,
|
||||||
|
searchConversation,
|
||||||
|
searchConversationName,
|
||||||
|
searchDisabled,
|
||||||
searchTerm,
|
searchTerm,
|
||||||
|
startSearchCounter,
|
||||||
}: Readonly<LeftPaneSearchPropsType>) {
|
}: Readonly<LeftPaneSearchPropsType>) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.conversationResults = conversationResults;
|
|
||||||
this.contactResults = contactResults;
|
this.contactResults = contactResults;
|
||||||
|
this.conversationResults = conversationResults;
|
||||||
this.messageResults = messageResults;
|
this.messageResults = messageResults;
|
||||||
this.searchConversationName = searchConversationName;
|
|
||||||
this.primarySendsSms = primarySendsSms;
|
this.primarySendsSms = primarySendsSms;
|
||||||
|
this.searchConversation = searchConversation;
|
||||||
|
this.searchConversationName = searchConversationName;
|
||||||
|
this.searchDisabled = searchDisabled;
|
||||||
this.searchTerm = searchTerm;
|
this.searchTerm = searchTerm;
|
||||||
|
this.startSearchCounter = startSearchCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
override getSearchInput({
|
||||||
|
clearConversationSearch,
|
||||||
|
clearSearch,
|
||||||
|
i18n,
|
||||||
|
updateSearchTerm,
|
||||||
|
}: Readonly<{
|
||||||
|
clearConversationSearch: () => unknown;
|
||||||
|
clearSearch: () => unknown;
|
||||||
|
i18n: LocalizerType;
|
||||||
|
updateSearchTerm: (searchTerm: string) => unknown;
|
||||||
|
}>): ReactChild {
|
||||||
|
return (
|
||||||
|
<LeftPaneMainSearchInput
|
||||||
|
clearConversationSearch={clearConversationSearch}
|
||||||
|
clearSearch={clearSearch}
|
||||||
|
disabled={this.searchDisabled}
|
||||||
|
i18n={i18n}
|
||||||
|
searchConversation={this.searchConversation}
|
||||||
|
searchTerm={this.searchTerm}
|
||||||
|
startSearchCounter={this.startSearchCounter}
|
||||||
|
updateSearchTerm={updateSearchTerm}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
override getPreRowsNode({
|
override getPreRowsNode({
|
||||||
i18n,
|
i18n,
|
||||||
}: Readonly<{ i18n: LocalizerType }>): null | ReactChild {
|
}: Readonly<{
|
||||||
|
i18n: LocalizerType;
|
||||||
|
}>): ReactChild | null {
|
||||||
const mightHaveSearchResults = this.allResults().some(
|
const mightHaveSearchResults = this.allResults().some(
|
||||||
searchResult => searchResult.isLoading || searchResult.results.length
|
searchResult => searchResult.isLoading || searchResult.results.length
|
||||||
);
|
);
|
||||||
|
|
||||||
if (mightHaveSearchResults) {
|
if (mightHaveSearchResults) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2019-2021 Signal Messenger, LLC
|
// Copyright 2019-2022 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import memoizee from 'memoizee';
|
import memoizee from 'memoizee';
|
||||||
|
@ -133,25 +133,6 @@ export const getSelectedConversationId = createSelector(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getSelectedConversation = createSelector(
|
|
||||||
getSelectedConversationId,
|
|
||||||
getConversationLookup,
|
|
||||||
(
|
|
||||||
selectedConversationId: string | undefined,
|
|
||||||
conversationLookup: ConversationLookupType
|
|
||||||
): undefined | ConversationType => {
|
|
||||||
if (!selectedConversationId) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
const conversation = getOwn(conversationLookup, selectedConversationId);
|
|
||||||
assert(
|
|
||||||
conversation,
|
|
||||||
'getSelectedConversation: could not find selected conversation in lookup; returning undefined'
|
|
||||||
);
|
|
||||||
return conversation;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
type SelectedMessageType = {
|
type SelectedMessageType = {
|
||||||
id: string;
|
id: string;
|
||||||
counter: number;
|
counter: number;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2019-2021 Signal Messenger, LLC
|
// Copyright 2019-2022 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import memoizee from 'memoizee';
|
import memoizee from 'memoizee';
|
||||||
|
@ -95,7 +95,14 @@ export const getSearchResults = createSelector(
|
||||||
state: SearchStateType,
|
state: SearchStateType,
|
||||||
searchConversationName,
|
searchConversationName,
|
||||||
conversationLookup: ConversationLookupType
|
conversationLookup: ConversationLookupType
|
||||||
): Omit<LeftPaneSearchPropsType, 'primarySendsSms'> => {
|
): Pick<
|
||||||
|
LeftPaneSearchPropsType,
|
||||||
|
| 'conversationResults'
|
||||||
|
| 'contactResults'
|
||||||
|
| 'messageResults'
|
||||||
|
| 'searchConversationName'
|
||||||
|
| 'searchTerm'
|
||||||
|
> => {
|
||||||
const {
|
const {
|
||||||
contactIds,
|
contactIds,
|
||||||
conversationIds,
|
conversationIds,
|
||||||
|
|
|
@ -118,12 +118,18 @@ const getModeSpecificProps = (
|
||||||
return {
|
return {
|
||||||
mode: LeftPaneMode.Search,
|
mode: LeftPaneMode.Search,
|
||||||
primarySendsSms,
|
primarySendsSms,
|
||||||
|
searchConversation: getSearchConversation(state),
|
||||||
|
searchDisabled: state.network.challengeStatus !== 'idle',
|
||||||
|
startSearchCounter: getStartSearchCounter(state),
|
||||||
...getSearchResults(state),
|
...getSearchResults(state),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
mode: LeftPaneMode.Inbox,
|
mode: LeftPaneMode.Inbox,
|
||||||
isAboutToSearchInAConversation: getIsSearchingInAConversation(state),
|
isAboutToSearchInAConversation: getIsSearchingInAConversation(state),
|
||||||
|
searchConversation: getSearchConversation(state),
|
||||||
|
searchDisabled: state.network.challengeStatus !== 'idle',
|
||||||
|
searchTerm: getQuery(state),
|
||||||
startSearchCounter: getStartSearchCounter(state),
|
startSearchCounter: getStartSearchCounter(state),
|
||||||
...getLeftPaneLists(state),
|
...getLeftPaneLists(state),
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2019-2021 Signal Messenger, LLC
|
// Copyright 2019-2022 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
@ -8,11 +8,6 @@ import { MainHeader } from '../../components/MainHeader';
|
||||||
import type { StateType } from '../reducer';
|
import type { StateType } from '../reducer';
|
||||||
|
|
||||||
import { getPreferredBadgeSelector } from '../selectors/badges';
|
import { getPreferredBadgeSelector } from '../selectors/badges';
|
||||||
import {
|
|
||||||
getQuery,
|
|
||||||
getSearchConversation,
|
|
||||||
getStartSearchCounter,
|
|
||||||
} from '../selectors/search';
|
|
||||||
import {
|
import {
|
||||||
getIntl,
|
getIntl,
|
||||||
getRegionCode,
|
getRegionCode,
|
||||||
|
@ -21,18 +16,13 @@ import {
|
||||||
getUserNumber,
|
getUserNumber,
|
||||||
getUserUuid,
|
getUserUuid,
|
||||||
} from '../selectors/user';
|
} from '../selectors/user';
|
||||||
import { getMe, getSelectedConversation } from '../selectors/conversations';
|
import { getMe } from '../selectors/conversations';
|
||||||
|
|
||||||
const mapStateToProps = (state: StateType) => {
|
const mapStateToProps = (state: StateType) => {
|
||||||
const me = getMe(state);
|
const me = getMe(state);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
disabled: state.network.challengeStatus !== 'idle',
|
|
||||||
hasPendingUpdate: Boolean(state.updates.didSnooze),
|
hasPendingUpdate: Boolean(state.updates.didSnooze),
|
||||||
searchTerm: getQuery(state),
|
|
||||||
searchConversation: getSearchConversation(state),
|
|
||||||
selectedConversation: getSelectedConversation(state),
|
|
||||||
startSearchCounter: getStartSearchCounter(state),
|
|
||||||
regionCode: getRegionCode(state),
|
regionCode: getRegionCode(state),
|
||||||
ourConversationId: getUserConversationId(state),
|
ourConversationId: getUserConversationId(state),
|
||||||
ourNumber: getUserNumber(state),
|
ourNumber: getUserNumber(state),
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2019-2021 Signal Messenger, LLC
|
// Copyright 2019-2022 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import { assert } from 'chai';
|
import { assert } from 'chai';
|
||||||
|
@ -39,7 +39,6 @@ import {
|
||||||
getNumberOfMessagesPendingBecauseOfVerification,
|
getNumberOfMessagesPendingBecauseOfVerification,
|
||||||
getPlaceholderContact,
|
getPlaceholderContact,
|
||||||
getRecommendedGroupSizeModalState,
|
getRecommendedGroupSizeModalState,
|
||||||
getSelectedConversation,
|
|
||||||
getSelectedConversationId,
|
getSelectedConversationId,
|
||||||
hasGroupCreationError,
|
hasGroupCreationError,
|
||||||
isCreatingGroup,
|
isCreatingGroup,
|
||||||
|
@ -1744,36 +1743,6 @@ describe('both/state/selectors/conversations', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#getSelectedConversation', () => {
|
|
||||||
it('returns undefined if no conversation is selected', () => {
|
|
||||||
const state = {
|
|
||||||
...getEmptyRootState(),
|
|
||||||
conversations: {
|
|
||||||
...getEmptyState(),
|
|
||||||
conversationLookup: {
|
|
||||||
abc123: makeConversation('abc123'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
assert.isUndefined(getSelectedConversation(state));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns the selected conversation', () => {
|
|
||||||
const conversation = makeConversation('abc123');
|
|
||||||
const state = {
|
|
||||||
...getEmptyRootState(),
|
|
||||||
conversations: {
|
|
||||||
...getEmptyState(),
|
|
||||||
conversationLookup: {
|
|
||||||
abc123: conversation,
|
|
||||||
},
|
|
||||||
selectedConversationId: 'abc123',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
assert.strictEqual(getSelectedConversation(state), conversation);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#getContactNameColorSelector', () => {
|
describe('#getContactNameColorSelector', () => {
|
||||||
it('returns the right color order sorted by UUID ASC', () => {
|
it('returns the right color order sorted by UUID ASC', () => {
|
||||||
const group = makeConversation('group');
|
const group = makeConversation('group');
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2021 Signal Messenger, LLC
|
// Copyright 2021-2022 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import { assert } from 'chai';
|
import { assert } from 'chai';
|
||||||
|
@ -12,10 +12,13 @@ import { LeftPaneInboxHelper } from '../../../components/leftPane/LeftPaneInboxH
|
||||||
|
|
||||||
describe('LeftPaneInboxHelper', () => {
|
describe('LeftPaneInboxHelper', () => {
|
||||||
const defaultProps: LeftPaneInboxPropsType = {
|
const defaultProps: LeftPaneInboxPropsType = {
|
||||||
conversations: [],
|
|
||||||
pinnedConversations: [],
|
|
||||||
archivedConversations: [],
|
archivedConversations: [],
|
||||||
|
conversations: [],
|
||||||
isAboutToSearchInAConversation: false,
|
isAboutToSearchInAConversation: false,
|
||||||
|
pinnedConversations: [],
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
searchTerm: '',
|
||||||
startSearchCounter: 0,
|
startSearchCounter: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2021 Signal Messenger, LLC
|
// Copyright 2021-2022 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import { assert } from 'chai';
|
import { assert } from 'chai';
|
||||||
|
@ -23,6 +23,9 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
messageResults: { isLoading: false, results: [] },
|
messageResults: { isLoading: false, results: [] },
|
||||||
searchTerm: 'foo',
|
searchTerm: 'foo',
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.isUndefined(
|
assert.isUndefined(
|
||||||
|
@ -44,6 +47,9 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
messageResults: { isLoading: true },
|
messageResults: { isLoading: true },
|
||||||
searchTerm: 'foo',
|
searchTerm: 'foo',
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
}).getRowCount(),
|
}).getRowCount(),
|
||||||
100
|
100
|
||||||
);
|
);
|
||||||
|
@ -57,6 +63,9 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
messageResults: { isLoading: true },
|
messageResults: { isLoading: true },
|
||||||
searchTerm: 'foo',
|
searchTerm: 'foo',
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
}).getRowCount(),
|
}).getRowCount(),
|
||||||
100
|
100
|
||||||
);
|
);
|
||||||
|
@ -67,6 +76,9 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
messageResults: { isLoading: false, results: [fakeMessage()] },
|
messageResults: { isLoading: false, results: [fakeMessage()] },
|
||||||
searchTerm: 'foo',
|
searchTerm: 'foo',
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
}).getRowCount(),
|
}).getRowCount(),
|
||||||
100
|
100
|
||||||
);
|
);
|
||||||
|
@ -79,6 +91,9 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
messageResults: { isLoading: false, results: [] },
|
messageResults: { isLoading: false, results: [] },
|
||||||
searchTerm: 'foo',
|
searchTerm: 'foo',
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.strictEqual(helper.getRowCount(), 0);
|
assert.strictEqual(helper.getRowCount(), 0);
|
||||||
|
@ -94,6 +109,9 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
messageResults: { isLoading: false, results: [fakeMessage()] },
|
messageResults: { isLoading: false, results: [fakeMessage()] },
|
||||||
searchTerm: 'foo',
|
searchTerm: 'foo',
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.strictEqual(helper.getRowCount(), 5);
|
assert.strictEqual(helper.getRowCount(), 5);
|
||||||
|
@ -109,6 +127,9 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
messageResults: { isLoading: true },
|
messageResults: { isLoading: true },
|
||||||
searchTerm: 'foo',
|
searchTerm: 'foo',
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
}),
|
}),
|
||||||
new LeftPaneSearchHelper({
|
new LeftPaneSearchHelper({
|
||||||
conversationResults: {
|
conversationResults: {
|
||||||
|
@ -119,6 +140,9 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
messageResults: { isLoading: true },
|
messageResults: { isLoading: true },
|
||||||
searchTerm: 'foo',
|
searchTerm: 'foo',
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
}),
|
}),
|
||||||
new LeftPaneSearchHelper({
|
new LeftPaneSearchHelper({
|
||||||
conversationResults: { isLoading: true },
|
conversationResults: { isLoading: true },
|
||||||
|
@ -126,6 +150,9 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
messageResults: { isLoading: false, results: [fakeMessage()] },
|
messageResults: { isLoading: false, results: [fakeMessage()] },
|
||||||
searchTerm: 'foo',
|
searchTerm: 'foo',
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -159,6 +186,9 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
messageResults: { isLoading: false, results: messages },
|
messageResults: { isLoading: false, results: messages },
|
||||||
searchTerm: 'foo',
|
searchTerm: 'foo',
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.deepEqual(helper.getRow(0), {
|
assert.deepEqual(helper.getRow(0), {
|
||||||
|
@ -208,6 +238,9 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
messageResults: { isLoading: false, results: messages },
|
messageResults: { isLoading: false, results: messages },
|
||||||
searchTerm: 'foo',
|
searchTerm: 'foo',
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.deepEqual(helper.getRow(0), {
|
assert.deepEqual(helper.getRow(0), {
|
||||||
|
@ -248,6 +281,9 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
messageResults: { isLoading: false, results: messages },
|
messageResults: { isLoading: false, results: messages },
|
||||||
searchTerm: 'foo',
|
searchTerm: 'foo',
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.deepEqual(helper.getRow(0), {
|
assert.deepEqual(helper.getRow(0), {
|
||||||
|
@ -290,6 +326,9 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
messageResults: { isLoading: false, results: [] },
|
messageResults: { isLoading: false, results: [] },
|
||||||
searchTerm: 'foo',
|
searchTerm: 'foo',
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.deepEqual(helper.getRow(0), {
|
assert.deepEqual(helper.getRow(0), {
|
||||||
|
@ -324,6 +363,9 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
messageResults: { isLoading: true },
|
messageResults: { isLoading: true },
|
||||||
searchTerm: 'foo',
|
searchTerm: 'foo',
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
}),
|
}),
|
||||||
new LeftPaneSearchHelper({
|
new LeftPaneSearchHelper({
|
||||||
conversationResults: {
|
conversationResults: {
|
||||||
|
@ -334,6 +376,9 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
messageResults: { isLoading: true },
|
messageResults: { isLoading: true },
|
||||||
searchTerm: 'foo',
|
searchTerm: 'foo',
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
}),
|
}),
|
||||||
new LeftPaneSearchHelper({
|
new LeftPaneSearchHelper({
|
||||||
conversationResults: { isLoading: true },
|
conversationResults: { isLoading: true },
|
||||||
|
@ -341,6 +386,9 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
messageResults: { isLoading: false, results: [fakeMessage()] },
|
messageResults: { isLoading: false, results: [fakeMessage()] },
|
||||||
searchTerm: 'foo',
|
searchTerm: 'foo',
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -362,6 +410,9 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
},
|
},
|
||||||
searchTerm: 'foo',
|
searchTerm: 'foo',
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
});
|
});
|
||||||
assert.isTrue(helper.isScrollable());
|
assert.isTrue(helper.isScrollable());
|
||||||
});
|
});
|
||||||
|
@ -381,6 +432,9 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
},
|
},
|
||||||
searchTerm: 'foo',
|
searchTerm: 'foo',
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.isFalse(
|
assert.isFalse(
|
||||||
|
@ -396,6 +450,9 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
},
|
},
|
||||||
searchTerm: 'bar',
|
searchTerm: 'bar',
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -407,6 +464,9 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
messageResults: { isLoading: true },
|
messageResults: { isLoading: true },
|
||||||
searchTerm: 'foo',
|
searchTerm: 'foo',
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.isFalse(
|
assert.isFalse(
|
||||||
|
@ -419,6 +479,9 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
messageResults: { isLoading: true },
|
messageResults: { isLoading: true },
|
||||||
searchTerm: 'bar',
|
searchTerm: 'bar',
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -430,6 +493,9 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
messageResults: { isLoading: false, results: [fakeMessage()] },
|
messageResults: { isLoading: false, results: [fakeMessage()] },
|
||||||
searchTerm: 'foo',
|
searchTerm: 'foo',
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.isTrue(
|
assert.isTrue(
|
||||||
|
@ -442,6 +508,9 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
messageResults: { isLoading: false, results: [fakeMessage()] },
|
messageResults: { isLoading: false, results: [fakeMessage()] },
|
||||||
searchTerm: 'foo',
|
searchTerm: 'foo',
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -456,6 +525,9 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
messageResults: { isLoading: false, results: [] },
|
messageResults: { isLoading: false, results: [] },
|
||||||
searchTerm: 'foo',
|
searchTerm: 'foo',
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.isTrue(
|
assert.isTrue(
|
||||||
|
@ -468,6 +540,9 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
messageResults: { isLoading: true },
|
messageResults: { isLoading: true },
|
||||||
searchTerm: 'bar',
|
searchTerm: 'bar',
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
@ -7488,20 +7488,11 @@
|
||||||
"updated": "2021-10-11T21:21:08.188Z"
|
"updated": "2021-10-11T21:21:08.188Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"rule": "React-createRef",
|
"rule": "React-useRef",
|
||||||
"path": "ts/components/MainHeader.js",
|
"path": "ts/components/LeftPaneMainSearchInput.tsx",
|
||||||
"line": " this.inputRef = react_1.default.createRef();",
|
"line": " const inputRef = useRef<HTMLInputElement | null>(null);",
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2020-02-14T20:02:37.507Z",
|
"updated": "2022-01-26T23:11:05.369Z"
|
||||||
"reasonDetail": "Used only to set focus"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rule": "React-createRef",
|
|
||||||
"path": "ts/components/MainHeader.tsx",
|
|
||||||
"line": " this.inputRef = React.createRef();",
|
|
||||||
"reasonCategory": "usageTrusted",
|
|
||||||
"updated": "2020-02-14T20:02:37.507Z",
|
|
||||||
"reasonDetail": "Used only to set focus"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"rule": "React-useRef",
|
"rule": "React-useRef",
|
||||||
|
@ -8411,4 +8402,4 @@
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2021-09-17T21:02:59.414Z"
|
"updated": "2021-09-17T21:02:59.414Z"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue