Address alpha feedback

This commit is contained in:
Scott Nonnenberg 2019-08-20 12:34:52 -07:00
parent 191f5860a8
commit 90c2a97aa7
9 changed files with 78 additions and 42 deletions

View file

@ -186,7 +186,7 @@
this.maybeGrabLinkPreview.bind(this), this.maybeGrabLinkPreview.bind(this),
200 200
); );
this.debouncedSaveDraft = _.debounce(this.saveDraft.bind(this), 200); this.debouncedSaveDraft = _.debounce(this.saveDraft.bind(this), 2000);
this.render(); this.render();
@ -2149,6 +2149,7 @@
try { try {
this.unload('delete messages'); this.unload('delete messages');
await this.model.destroyMessages(); await this.model.destroyMessages();
Whisper.events.trigger('unloadConversation', this.model.id);
this.model.updateLastMessage(); this.model.updateLastMessage();
} catch (error) { } catch (error) {
window.log.error( window.log.error(
@ -2421,10 +2422,10 @@
}, },
async saveDraft(messageText) { async saveDraft(messageText) {
if ( const trimmed =
(this.model.get('draft') && !messageText) || messageText && messageText.length > 0 ? messageText.trim() : '';
messageText.length === 0
) { if ((this.model.get('draft') && !messageText) || trimmed.length === 0) {
this.model.set({ this.model.set({
draft: null, draft: null,
}); });

View file

@ -47,6 +47,11 @@
// Make sure poppers are positioned properly // Make sure poppers are positioned properly
window.dispatchEvent(new Event('resize')); window.dispatchEvent(new Event('resize'));
}, },
onUnload(conversationId) {
if (this.lastConversation.id === conversationId) {
this.lastConversation = null;
}
},
}); });
Whisper.AppLoadingScreen = Whisper.View.extend({ Whisper.AppLoadingScreen = Whisper.View.extend({
@ -75,6 +80,9 @@
el: this.$('.conversation-stack'), el: this.$('.conversation-stack'),
model: { window: options.window }, model: { window: options.window },
}); });
Whisper.events.on('unloadConversation', conversationId => {
this.conversation_stack.onUnload(conversationId);
});
if (!options.initialLoadComplete) { if (!options.initialLoadComplete) {
this.appLoadingScreen = new Whisper.AppLoadingScreen(); this.appLoadingScreen = new Whisper.AppLoadingScreen();

View file

@ -202,7 +202,8 @@
} }
], ],
"target": [ "target": [
"zip", "dmg" "zip",
"dmg"
], ],
"bundleVersion": "1" "bundleVersion": "1"
}, },

View file

@ -2410,7 +2410,7 @@
border: solid 1px $color-gray-15; border: solid 1px $color-gray-15;
padding-left: 30px; padding-left: 30px;
padding-right: 30px; padding-right: 5px;
color: $color-gray-90; color: $color-gray-90;
font-size: 14px; font-size: 14px;
@ -2425,6 +2425,10 @@
} }
} }
.module-main-header__search__input--with-text {
padding-right: 30px;
}
.module-main-header__search__input--in-conversation { .module-main-header__search__input--in-conversation {
padding-left: 50px; padding-left: 50px;
} }
@ -2453,6 +2457,10 @@
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
// Overriding some default button styling
border: none;
padding: 0;
} }
.module-main-header__search__in-conversation-pill__avatar-container { .module-main-header__search__in-conversation-pill__avatar-container {
margin-left: 4px; margin-left: 4px;

View file

@ -197,15 +197,15 @@ export class MainHeader extends React.Component<PropsType> {
/> />
<div className="module-main-header__search"> <div className="module-main-header__search">
{searchConversationId ? ( {searchConversationId ? (
<div className="module-main-header__search__in-conversation-pill"> <button
className="module-main-header__search__in-conversation-pill"
onClick={this.clearSearch}
>
<div className="module-main-header__search__in-conversation-pill__avatar-container"> <div className="module-main-header__search__in-conversation-pill__avatar-container">
<div className="module-main-header__search__in-conversation-pill__avatar" /> <div className="module-main-header__search__in-conversation-pill__avatar" />
</div> </div>
<button <div className="module-main-header__search__in-conversation-pill__x-button" />
className="module-main-header__search__in-conversation-pill__x-button" </button>
onClick={this.clearSearch}
/>
</div>
) : ( ) : (
<button <button
className="module-main-header__search__icon" className="module-main-header__search__icon"
@ -217,6 +217,9 @@ export class MainHeader extends React.Component<PropsType> {
ref={this.inputRef} ref={this.inputRef}
className={classNames( className={classNames(
'module-main-header__search__input', 'module-main-header__search__input',
searchTerm
? 'module-main-header__search__input--with-text'
: null,
searchConversationId searchConversationId
? 'module-main-header__search__input--in-conversation' ? 'module-main-header__search__input--in-conversation'
: null : null

View file

@ -578,10 +578,7 @@ export class Timeline extends React.PureComponent<Props, State> {
public getRowCount() { public getRowCount() {
const { haveOldest, oldestUnreadIndex, typingContact } = this.props; const { haveOldest, oldestUnreadIndex, typingContact } = this.props;
const { items } = this.props; const { items } = this.props;
const itemsCount = items && items.length ? items.length : 0;
if (!items || items.length < 1) {
return 0;
}
let extraRows = 0; let extraRows = 0;
@ -597,7 +594,7 @@ export class Timeline extends React.PureComponent<Props, State> {
extraRows += 1; extraRows += 1;
} }
return items.length + extraRows; return itemsCount + extraRows;
} }
public fromRowToItemIndex(row: number): number | undefined { public fromRowToItemIndex(row: number): number | undefined {
@ -848,13 +845,13 @@ export class Timeline extends React.PureComponent<Props, State> {
areUnreadBelowCurrentPosition, areUnreadBelowCurrentPosition,
} = this.state; } = this.state;
if (!items || items.length < 1) {
return null;
}
const rowCount = this.getRowCount(); const rowCount = this.getRowCount();
const scrollToIndex = this.getScrollTarget(); const scrollToIndex = this.getScrollTarget();
if (!items || rowCount === 0) {
return null;
}
return ( return (
<div className="module-timeline"> <div className="module-timeline">
<AutoSizer> <AutoSizer>

View file

@ -11,6 +11,11 @@ import {
} from 'lodash'; } from 'lodash';
import { trigger } from '../../shims/events'; import { trigger } from '../../shims/events';
import { NoopActionType } from './noop'; import { NoopActionType } from './noop';
import {
AttachmentType,
isImageAttachment,
isVideoAttachment,
} from '../../types/attachment';
// State // State
@ -53,6 +58,7 @@ export type MessageType = {
quote?: { author: string }; quote?: { author: string };
received_at: number; received_at: number;
hasSignalAccount?: boolean; hasSignalAccount?: boolean;
attachments: Array<AttachmentType>;
// No need to go beyond this; unused at this stage, since this goes into // No need to go beyond this; unused at this stage, since this goes into
// a reducer still in plain JavaScript and comes out well-formed // a reducer still in plain JavaScript and comes out well-formed
@ -511,10 +517,22 @@ function hasMessageHeightChanged(
message: MessageType, message: MessageType,
previous: MessageType previous: MessageType
): Boolean { ): Boolean {
return ( const visualAttachmentNoLongerPending =
previous.attachments &&
previous.attachments[0] &&
previous.attachments[0].pending &&
message.attachments &&
message.attachments.length === 1 &&
message.attachments[0] &&
(isImageAttachment(message.attachments[0]) ||
isVideoAttachment(message.attachments[0])) &&
!message.attachments[0].pending;
const signalAccountChanged =
Boolean(message.hasSignalAccount || previous.hasSignalAccount) && Boolean(message.hasSignalAccount || previous.hasSignalAccount) &&
message.hasSignalAccount !== previous.hasSignalAccount message.hasSignalAccount !== previous.hasSignalAccount;
);
return visualAttachmentNoLongerPending || signalAccountChanged;
} }
// tslint:disable-next-line cyclomatic-complexity max-func-body-length // tslint:disable-next-line cyclomatic-complexity max-func-body-length

View file

@ -53,9 +53,9 @@ export const getSearchConversationName = createSelector(
export const isSearching = createSelector( export const isSearching = createSelector(
getSearch, getSearch,
(state: SearchStateType) => { (state: SearchStateType) => {
const { query, searchConversationId } = state; const { query } = state;
return (query && query.trim().length > 1) || searchConversationId; return query && query.trim().length > 1;
} }
); );
@ -71,7 +71,7 @@ export const getSearchResults = createSelector(
regionCode: string, regionCode: string,
lookup: ConversationLookupType, lookup: ConversationLookupType,
selectedConversation?: string selectedConversation?: string
): SearchResultsPropsType => { ): SearchResultsPropsType | undefined => {
const { const {
contacts, contacts,
conversations, conversations,

View file

@ -486,7 +486,7 @@
"rule": "jQuery-$(", "rule": "jQuery-$(",
"path": "js/views/inbox_view.js", "path": "js/views/inbox_view.js",
"line": " this.$('.message').text(message);", "line": " this.$('.message').text(message);",
"lineNumber": 58, "lineNumber": 63,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2019-07-31T00:19:18.696Z", "updated": "2019-07-31T00:19:18.696Z",
"reasonDetail": "Hardcoded selector" "reasonDetail": "Hardcoded selector"
@ -495,7 +495,7 @@
"rule": "jQuery-$(", "rule": "jQuery-$(",
"path": "js/views/inbox_view.js", "path": "js/views/inbox_view.js",
"line": " el: this.$('.conversation-stack'),", "line": " el: this.$('.conversation-stack'),",
"lineNumber": 75, "lineNumber": 80,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2019-07-31T00:19:18.696Z", "updated": "2019-07-31T00:19:18.696Z",
"reasonDetail": "Hardcoded selector" "reasonDetail": "Hardcoded selector"
@ -504,7 +504,7 @@
"rule": "jQuery-prependTo(", "rule": "jQuery-prependTo(",
"path": "js/views/inbox_view.js", "path": "js/views/inbox_view.js",
"line": " this.appLoadingScreen.$el.prependTo(this.el);", "line": " this.appLoadingScreen.$el.prependTo(this.el);",
"lineNumber": 82, "lineNumber": 90,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2019-07-31T00:19:18.696Z", "updated": "2019-07-31T00:19:18.696Z",
"reasonDetail": "Known DOM elements" "reasonDetail": "Known DOM elements"
@ -513,7 +513,7 @@
"rule": "jQuery-append(", "rule": "jQuery-append(",
"path": "js/views/inbox_view.js", "path": "js/views/inbox_view.js",
"line": " .append(this.networkStatusView.render().el);", "line": " .append(this.networkStatusView.render().el);",
"lineNumber": 99, "lineNumber": 107,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2019-07-31T00:19:18.696Z", "updated": "2019-07-31T00:19:18.696Z",
"reasonDetail": "Known DOM elements" "reasonDetail": "Known DOM elements"
@ -522,7 +522,7 @@
"rule": "jQuery-prependTo(", "rule": "jQuery-prependTo(",
"path": "js/views/inbox_view.js", "path": "js/views/inbox_view.js",
"line": " banner.$el.prependTo(this.$el);", "line": " banner.$el.prependTo(this.$el);",
"lineNumber": 103, "lineNumber": 111,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2019-07-31T00:19:18.696Z", "updated": "2019-07-31T00:19:18.696Z",
"reasonDetail": "Known DOM elements" "reasonDetail": "Known DOM elements"
@ -531,7 +531,7 @@
"rule": "jQuery-appendTo(", "rule": "jQuery-appendTo(",
"path": "js/views/inbox_view.js", "path": "js/views/inbox_view.js",
"line": " toast.$el.appendTo(this.$el);", "line": " toast.$el.appendTo(this.$el);",
"lineNumber": 109, "lineNumber": 117,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2019-07-31T00:19:18.696Z", "updated": "2019-07-31T00:19:18.696Z",
"reasonDetail": "Known DOM elements" "reasonDetail": "Known DOM elements"
@ -540,7 +540,7 @@
"rule": "jQuery-$(", "rule": "jQuery-$(",
"path": "js/views/inbox_view.js", "path": "js/views/inbox_view.js",
"line": " this.$('.left-pane-placeholder').append(this.leftPaneView.el);", "line": " this.$('.left-pane-placeholder').append(this.leftPaneView.el);",
"lineNumber": 129, "lineNumber": 137,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2019-07-31T00:19:18.696Z", "updated": "2019-07-31T00:19:18.696Z",
"reasonDetail": "Known DOM elements" "reasonDetail": "Known DOM elements"
@ -549,7 +549,7 @@
"rule": "jQuery-append(", "rule": "jQuery-append(",
"path": "js/views/inbox_view.js", "path": "js/views/inbox_view.js",
"line": " this.$('.left-pane-placeholder').append(this.leftPaneView.el);", "line": " this.$('.left-pane-placeholder').append(this.leftPaneView.el);",
"lineNumber": 129, "lineNumber": 137,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2019-07-31T00:19:18.696Z", "updated": "2019-07-31T00:19:18.696Z",
"reasonDetail": "Known DOM elements" "reasonDetail": "Known DOM elements"
@ -558,7 +558,7 @@
"rule": "jQuery-$(", "rule": "jQuery-$(",
"path": "js/views/inbox_view.js", "path": "js/views/inbox_view.js",
"line": " if (e && this.$(e.target).closest('.placeholder').length) {", "line": " if (e && this.$(e.target).closest('.placeholder').length) {",
"lineNumber": 172, "lineNumber": 180,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2019-07-31T00:19:18.696Z", "updated": "2019-07-31T00:19:18.696Z",
"reasonDetail": "Known DOM elements" "reasonDetail": "Known DOM elements"
@ -567,7 +567,7 @@
"rule": "jQuery-$(", "rule": "jQuery-$(",
"path": "js/views/inbox_view.js", "path": "js/views/inbox_view.js",
"line": " this.$('#header, .gutter').addClass('inactive');", "line": " this.$('#header, .gutter').addClass('inactive');",
"lineNumber": 176, "lineNumber": 184,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2019-07-31T00:19:18.696Z", "updated": "2019-07-31T00:19:18.696Z",
"reasonDetail": "Hardcoded selector" "reasonDetail": "Hardcoded selector"
@ -576,7 +576,7 @@
"rule": "jQuery-$(", "rule": "jQuery-$(",
"path": "js/views/inbox_view.js", "path": "js/views/inbox_view.js",
"line": " this.$('.conversation-stack').addClass('inactive');", "line": " this.$('.conversation-stack').addClass('inactive');",
"lineNumber": 180, "lineNumber": 188,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2019-07-31T00:19:18.696Z", "updated": "2019-07-31T00:19:18.696Z",
"reasonDetail": "Hardcoded selector" "reasonDetail": "Hardcoded selector"
@ -585,7 +585,7 @@
"rule": "jQuery-$(", "rule": "jQuery-$(",
"path": "js/views/inbox_view.js", "path": "js/views/inbox_view.js",
"line": " this.$('.conversation:first .menu').trigger('close');", "line": " this.$('.conversation:first .menu').trigger('close');",
"lineNumber": 182, "lineNumber": 190,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2019-07-31T00:19:18.696Z", "updated": "2019-07-31T00:19:18.696Z",
"reasonDetail": "Hardcoded selector" "reasonDetail": "Hardcoded selector"
@ -594,7 +594,7 @@
"rule": "jQuery-$(", "rule": "jQuery-$(",
"path": "js/views/inbox_view.js", "path": "js/views/inbox_view.js",
"line": " if (e && this.$(e.target).closest('.capture-audio').length > 0) {", "line": " if (e && this.$(e.target).closest('.capture-audio').length > 0) {",
"lineNumber": 202, "lineNumber": 210,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2019-07-31T00:19:18.696Z", "updated": "2019-07-31T00:19:18.696Z",
"reasonDetail": "Known DOM elements" "reasonDetail": "Known DOM elements"
@ -603,7 +603,7 @@
"rule": "jQuery-$(", "rule": "jQuery-$(",
"path": "js/views/inbox_view.js", "path": "js/views/inbox_view.js",
"line": " this.$('.conversation:first .recorder').trigger('close');", "line": " this.$('.conversation:first .recorder').trigger('close');",
"lineNumber": 205, "lineNumber": 213,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2019-07-31T00:19:18.696Z", "updated": "2019-07-31T00:19:18.696Z",
"reasonDetail": "Hardcoded selector" "reasonDetail": "Hardcoded selector"