From 9b0a4c095e3c0be72f95e749cd7317e101041427 Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Tue, 28 Apr 2020 14:26:05 +1000 Subject: [PATCH 1/9] chat-js: fix scrolling to bottom fixes: #2778 fixes: #2782 --- pkg/interface/chat/src/js/components/chat.js | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/pkg/interface/chat/src/js/components/chat.js b/pkg/interface/chat/src/js/components/chat.js index c2e8b8faed..063d24de4e 100644 --- a/pkg/interface/chat/src/js/components/chat.js +++ b/pkg/interface/chat/src/js/components/chat.js @@ -31,7 +31,6 @@ export class ChatScreen extends Component { scrollLocked: false, // only for FF lastScrollHeight: null, - scrollBottom: true }; this.hasAskedForMessages = false; @@ -91,19 +90,14 @@ export class ChatScreen extends Component { this.hasAskedForMessages = false; } - // FF logic if ( - navigator.userAgent.includes("Firefox") && (props.length !== prevProps.length || props.envelopes.length !== prevProps.envelopes.length || getNumPending(props) !== this.lastNumPending || state.numPages !== prevState.numPages) ) { - if(state.scrollBottom) { - setTimeout(() => { - this.scrollToBottom(); - }) - } else { + this.scrollToBottom(); + if(navigator.userAgent.includes("Firefox")) { this.recalculateScrollTop(); } @@ -192,10 +186,7 @@ export class ChatScreen extends Component { this.setState({ numPages: 1, scrollLocked: false, - scrollBottom: true }); - } else if (navigator.userAgent.includes('Firefox')) { - this.setState({ scrollBottom: false }); } } else if (navigator.userAgent.includes("Safari")) { // Safari From fc1518dc08251c0a2625cb0364304825a01532d7 Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Tue, 28 Apr 2020 16:46:07 +1000 Subject: [PATCH 2/9] chat-js: fix behaviour of unread markers Fixes #2797 --- pkg/interface/chat/src/js/components/chat.js | 54 +++++++++++++------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/pkg/interface/chat/src/js/components/chat.js b/pkg/interface/chat/src/js/components/chat.js index 063d24de4e..1e315c86b2 100644 --- a/pkg/interface/chat/src/js/components/chat.js +++ b/pkg/interface/chat/src/js/components/chat.js @@ -29,6 +29,7 @@ export class ChatScreen extends Component { this.state = { numPages: 1, scrollLocked: false, + read: props.read, // only for FF lastScrollHeight: null, }; @@ -40,6 +41,8 @@ export class ChatScreen extends Component { this.onScroll = this.onScroll.bind(this); this.unreadMarker = null; + this.scrolledToMarker = false; + this.setUnreadMarker = this.setUnreadMarker.bind(this); moment.updateLocale('en', { calendar: { @@ -73,8 +76,13 @@ export class ChatScreen extends Component { this.askForMessages(); } + this.unreadMarker = null; + this.scrolledToMarker = false; this.setState( - { scrollLocked: false }, + { + scrollLocked: false, + read: props.read, + }, () => { this.scrollToBottom(); } @@ -88,6 +96,11 @@ export class ChatScreen extends Component { props.envelopes.length >= prevProps.envelopes.length + 10 ) { this.hasAskedForMessages = false; + } else if(props.length !== prevProps.length && + prevProps.length === prevProps.read + ) { + this.setState({ read: props.length }) + this.props.api.chat.read(this.props.station); } if ( @@ -183,6 +196,7 @@ export class ChatScreen extends Component { e.target.scrollHeight - Math.round(e.target.scrollTop) === e.target.clientHeight ) { + this.dismissUnread(); this.setState({ numPages: 1, scrollLocked: false, @@ -191,6 +205,7 @@ export class ChatScreen extends Component { } else if (navigator.userAgent.includes("Safari")) { // Safari if (e.target.scrollTop === 0) { + this.dismissUnread(); this.setState({ numPages: 1, scrollLocked: false @@ -212,20 +227,20 @@ export class ChatScreen extends Component { } else { console.log("Your browser is not supported."); } - if(!!this.unreadMarker) { - if( - !navigator.userAgent.includes('Firefox') && - e.target.scrollHeight - e.target.scrollTop - (e.target.clientHeight * 1.5) + this.unreadMarker.offsetTop > 50 - ) { - this.props.api.chat.read(this.props.station); - } else if(navigator.userAgent.includes('Firefox') && - this.unreadMarker.offsetTop - e.target.scrollTop - (e.target.clientHeight / 2) > 0 - ) { - this.props.api.chat.read(this.props.station); - } - + } + setUnreadMarker(ref) { + if(ref && !this.scrolledToMarker) { + this.setState({ scrollLocked: true }, () => { + ref.scrollIntoView({ block: 'center' }); + }); + this.scrolledToMarker = true; } + this.unreadMarker = ref; + } + + dismissUnread() { + this.props.api.chat.read(this.props.station); } chatWindow(unread) { @@ -282,11 +297,11 @@ export class ChatScreen extends Component { group={props.association} /> ); - if(unread > 0 && i === unread) { + if(unread > 0 && i === unread - 1) { return ( <> {messageElem} -
(this.unreadMarker = ref)} className="mv2 green2 flex items-center f9"> +

New messages below @@ -401,10 +416,13 @@ export class ChatScreen extends Component { : props.station.substr(1); } - const unread = props.length - props.read; + const unread = props.length - state.read; const unreadMsg = unread > 0 && messages[unread - 1]; + + const showUnreadNotice = props.length !== props.read && props.read === state.read; + return (

- { !!unreadMsg && ( + { !!unreadMsg && showUnreadNotice && ( props.api.chat.read(props.station)} + onRead={() => this.dismissUnread()} /> ) } {this.chatWindow(unread)} From 77925a45800f424b893aba7f14cbbc560f54e72c Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Tue, 28 Apr 2020 17:06:26 +1000 Subject: [PATCH 3/9] chat-js: fix unread indicators on small screens fixes #2804 --- pkg/interface/chat/src/js/components/chat.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/interface/chat/src/js/components/chat.js b/pkg/interface/chat/src/js/components/chat.js index 1e315c86b2..fa2ffdf761 100644 --- a/pkg/interface/chat/src/js/components/chat.js +++ b/pkg/interface/chat/src/js/components/chat.js @@ -302,7 +302,7 @@ export class ChatScreen extends Component { <> {messageElem}
-
+

New messages below

From e96bd35f819def2cd81f6073f2040114bcc67a5a Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Wed, 29 Apr 2020 12:49:14 +1000 Subject: [PATCH 4/9] various-js: pass props.size into flexBasis for sigil Fixes #2817 --- pkg/interface/chat/src/js/components/lib/icons/sigil.js | 2 +- pkg/interface/groups/src/js/components/lib/icons/sigil.js | 2 +- pkg/interface/launch/src/js/components/sigil.js | 2 +- pkg/interface/soto/src/js/components/lib/icons/sigil.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/interface/chat/src/js/components/lib/icons/sigil.js b/pkg/interface/chat/src/js/components/lib/icons/sigil.js index 2209ccab72..c9efb729db 100644 --- a/pkg/interface/chat/src/js/components/lib/icons/sigil.js +++ b/pkg/interface/chat/src/js/components/lib/icons/sigil.js @@ -32,7 +32,7 @@ export class Sigil extends Component { return (
{sigil({ patp: props.ship, diff --git a/pkg/interface/groups/src/js/components/lib/icons/sigil.js b/pkg/interface/groups/src/js/components/lib/icons/sigil.js index d996866ce3..202a9e5929 100644 --- a/pkg/interface/groups/src/js/components/lib/icons/sigil.js +++ b/pkg/interface/groups/src/js/components/lib/icons/sigil.js @@ -32,7 +32,7 @@ export class Sigil extends Component { return (
{sigil({ patp: props.ship, diff --git a/pkg/interface/launch/src/js/components/sigil.js b/pkg/interface/launch/src/js/components/sigil.js index 49650987bd..2ef775e8bc 100644 --- a/pkg/interface/launch/src/js/components/sigil.js +++ b/pkg/interface/launch/src/js/components/sigil.js @@ -17,7 +17,7 @@ export class Sigil extends Component { return (
+ style={{ flexBasis: props.size, backgroundColor: props.color }}> {sigil({ patp: props.ship, renderer: reactRenderer, diff --git a/pkg/interface/soto/src/js/components/lib/icons/sigil.js b/pkg/interface/soto/src/js/components/lib/icons/sigil.js index 8bd10a3791..2ef775e8bc 100644 --- a/pkg/interface/soto/src/js/components/lib/icons/sigil.js +++ b/pkg/interface/soto/src/js/components/lib/icons/sigil.js @@ -17,7 +17,7 @@ export class Sigil extends Component { return (
+ style={{ flexBasis: props.size, backgroundColor: props.color }}> {sigil({ patp: props.ship, renderer: reactRenderer, From eb6b50e0ca150a34a6fd4769bfe740f0ff501799 Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Wed, 29 Apr 2020 13:29:09 +1000 Subject: [PATCH 5/9] chat-js: truncate nicknames in autocomplete --- pkg/interface/chat/src/js/components/lib/ship-search.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/interface/chat/src/js/components/lib/ship-search.js b/pkg/interface/chat/src/js/components/lib/ship-search.js index e820e462ec..250fc0dcbf 100644 --- a/pkg/interface/chat/src/js/components/lib/ship-search.js +++ b/pkg/interface/chat/src/js/components/lib/ship-search.js @@ -20,6 +20,7 @@ function ShipSearchItem({ ship, contacts, selected, onSelect }) { nameStyle.color = hexToRgba(hex, 0.7); nameStyle.textShadow = '0px 0px 0px #000'; nameStyle.filter = 'contrast(1.3) saturate(1.5)'; + nameStyle.maxWidth = '200px'; sigilClass = 'v-mid'; nickname = contact.nickname; } @@ -28,7 +29,7 @@ function ShipSearchItem({ ship, contacts, selected, onSelect }) {
onSelect(ship)} className={cn( - 'f8 pv1 ph3 pointer hover-bg-gray1-d hover-bg-gray4 relative flex items-center', + 'f9 pv1 ph3 pointer hover-bg-gray1-d hover-bg-gray4 relative flex items-center', { 'white-d bg-gray0-d bg-white': !isSelected, 'black-d bg-gray1-d bg-gray4': isSelected @@ -38,7 +39,7 @@ function ShipSearchItem({ ship, contacts, selected, onSelect }) { > {nickname && ( -

+

{nickname}

)} From 17e1dd83622b5a1508bfe2a1716607be8f608262 Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Wed, 29 Apr 2020 13:37:58 +1000 Subject: [PATCH 6/9] chat-js: update read on initialisation --- pkg/interface/chat/src/js/components/chat.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/interface/chat/src/js/components/chat.js b/pkg/interface/chat/src/js/components/chat.js index fa2ffdf761..04f34432a7 100644 --- a/pkg/interface/chat/src/js/components/chat.js +++ b/pkg/interface/chat/src/js/components/chat.js @@ -103,6 +103,10 @@ export class ChatScreen extends Component { this.props.api.chat.read(this.props.station); } + if(!prevProps.chatInitialized && props.chatInitialized) { + this.setState({ read: props.read }) + } + if ( (props.length !== prevProps.length || props.envelopes.length !== prevProps.envelopes.length || From bdec28c541a4b134614e38621a5cb04f05656a66 Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Thu, 30 Apr 2020 11:35:03 +1000 Subject: [PATCH 7/9] chat-js: load all unreads and autoread on activity if the number of unread messages is larger that the number we are going to load, then load enough messages to display the unread marker. Additionally, only automatically read a message if the user has been active in the last minute. Freeze scroll position on inactivity. Also unconditionally scroll to the bottom upon sending your own message. --- pkg/interface/chat/src/js/components/chat.js | 165 +++++++++++------- .../chat/src/js/components/lib/chat-input.js | 2 + 2 files changed, 108 insertions(+), 59 deletions(-) diff --git a/pkg/interface/chat/src/js/components/chat.js b/pkg/interface/chat/src/js/components/chat.js index 04f34432a7..9f5bf8a77d 100644 --- a/pkg/interface/chat/src/js/components/chat.js +++ b/pkg/interface/chat/src/js/components/chat.js @@ -22,6 +22,36 @@ function getNumPending(props) { return result; } +const ACTIVITY_TIMEOUT = 60000; // a minute + +function scrollIsAtTop(container) { + if ((navigator.userAgent.includes("Safari") && + navigator.userAgent.includes("Chrome")) || + navigator.userAgent.includes("Firefox") + ) { + return container.scrollTop === 0; + } else if (navigator.userAgent.includes("Safari")) { + return container.scrollHeight + Math.round(container.scrollTop) <= + container.clientHeight + 10; + } else { + return false; + } +} + +function scrollIsAtBottom(container) { + if ((navigator.userAgent.includes("Safari") && + navigator.userAgent.includes("Chrome")) || + navigator.userAgent.includes("Firefox") + ) { + return container.scrollHeight - Math.round(container.scrollTop) <= + container.clientHeight + 10; + } else if (navigator.userAgent.includes("Safari")) { + return container.scrollTop === 0; + } else { + return false; + } +} + export class ChatScreen extends Component { constructor(props) { super(props); @@ -30,6 +60,7 @@ export class ChatScreen extends Component { numPages: 1, scrollLocked: false, read: props.read, + active: true, // only for FF lastScrollHeight: null, }; @@ -44,6 +75,10 @@ export class ChatScreen extends Component { this.scrolledToMarker = false; this.setUnreadMarker = this.setUnreadMarker.bind(this); + this.activityTimeout = true; + this.handleActivity = this.handleActivity.bind(this); + this.setInactive = this.setInactive.bind(this); + moment.updateLocale('en', { calendar: { sameDay: '[Today]', @@ -60,8 +95,39 @@ export class ChatScreen extends Component { componentDidMount() { this.askForMessages(); this.scrollToBottom(); + + document.addEventListener("mousemove", this.handleActivity, false); + document.addEventListener("mousedown", this.handleActivity, false); + document.addEventListener("keypress", this.handleActivity, false); + document.addEventListener("touchmove", this.handleActivity, false); + this.activityTimeout = setTimeout(this.setInactive, ACTIVITY_TIMEOUT); } + componentWillUnmount() { + document.removeEventListener("mousemove", this.handleActivity, false); + document.removeEventListener("mousedown", this.handleActivity, false); + document.removeEventListener("keypress", this.handleActivity, false); + document.removeEventListener("touchmove", this.handleActivity, false); + if(this.activityTimeout) { + clearTimeout(this.activityTimeout); + } + } + + handleActivity() { + if(!this.state.active) { + this.setState({ active: true }); + } + + if(this.activityTimeout) { + clearTimeout(this.activityTimeout); + this.activityTimeout = setTimeout(this.setInactive, ACTIVITY_TIMEOUT); + } + } + + setInactive() { + this.activityTimeout = null; + this.setState({ active: false, scrollLocked: true }); + } componentDidUpdate(prevProps, prevState) { const { props, state } = this; @@ -97,7 +163,8 @@ export class ChatScreen extends Component { ) { this.hasAskedForMessages = false; } else if(props.length !== prevProps.length && - prevProps.length === prevProps.read + prevProps.length === prevProps.read && + state.active ) { this.setState({ read: props.length }) this.props.api.chat.read(this.props.station); @@ -143,8 +210,16 @@ export class ChatScreen extends Component { let start = props.length - props.envelopes[props.envelopes.length - 1].number; if (start > 0) { - let end = start + 300 < props.length ? start + 300 : props.length; + const unread = props.length - props.read; + const unloadedUnread = unread - props.envelopes.length; + const willLoadUnread = unloadedUnread > 280; + const offset = willLoadUnread ? unloadedUnread + 20 : 300; + const end = start + offset < props.length ? start + offset : props.length; this.hasAskedForMessages = true; + if(willLoadUnread) { + // ensure unread marker is visible + this.setState({ numPages: Math.ceil(unread / 100) }); + } props.subscription.fetchMessages(start + 1, end, props.station); } } @@ -172,64 +247,28 @@ export class ChatScreen extends Component { } onScroll(e) { - if ( - (navigator.userAgent.includes("Safari") && - navigator.userAgent.includes("Chrome")) || - navigator.userAgent.includes("Firefox") - ) { - // Google Chrome and Firefox - if (e.target.scrollTop === 0) { - - // Save scroll position for FF - if (navigator.userAgent.includes('Firefox')) { - - this.setState({ - lastScrollHeight: e.target.scrollHeight - }) + if(scrollIsAtTop(e.target)) { + // Save scroll position for FF + if (navigator.userAgent.includes('Firefox')) { + this.setState({ + lastScrollHeight: e.target.scrollHeight + }); + } + this.setState( + { + numPages: this.state.numPages + 1, + scrollLocked: true + }, + () => { + this.askForMessages(); } - this.setState( - { - numPages: this.state.numPages + 1, - scrollLocked: true - }, - () => { - this.askForMessages(); - } - ); - } else if ( - e.target.scrollHeight - Math.round(e.target.scrollTop) === - e.target.clientHeight - ) { - this.dismissUnread(); - this.setState({ - numPages: 1, - scrollLocked: false, - }); - } - } else if (navigator.userAgent.includes("Safari")) { - // Safari - if (e.target.scrollTop === 0) { - this.dismissUnread(); - this.setState({ - numPages: 1, - scrollLocked: false - }); - } else if ( - e.target.scrollHeight + Math.round(e.target.scrollTop) <= - e.target.clientHeight + 10 - ) { - this.setState( - { - numPages: this.state.numPages + 1, - scrollLocked: true - }, - () => { - this.askForMessages(); - } - ); - } - } else { - console.log("Your browser is not supported."); + ); + } else if (scrollIsAtBottom(e.target)) { + this.dismissUnread(); + this.setState({ + numPages: 1, + scrollLocked: false + }); } } @@ -237,6 +276,13 @@ export class ChatScreen extends Component { if(ref && !this.scrolledToMarker) { this.setState({ scrollLocked: true }, () => { ref.scrollIntoView({ block: 'center' }); + if(scrollIsAtBottom(ref.offsetParent)) { + this.dismissUnread(); + this.setState({ + numPages: 1, + scrollLocked: false + }); + } }); this.scrolledToMarker = true; } @@ -478,6 +524,7 @@ export class ChatScreen extends Component { ownerContact={ownerContact} envelopes={props.envelopes} contacts={props.contacts} + onEnter={() => this.setState({ scrollLocked: false })} placeholder="Message..." />
diff --git a/pkg/interface/chat/src/js/components/lib/chat-input.js b/pkg/interface/chat/src/js/components/lib/chat-input.js index 6a61b57f19..ae94ca96f3 100644 --- a/pkg/interface/chat/src/js/components/lib/chat-input.js +++ b/pkg/interface/chat/src/js/components/lib/chat-input.js @@ -192,6 +192,8 @@ export class ChatInput extends Component { return; } + props.onEnter(); + if(state.code) { props.api.chat.message(props.station, `~${window.ship}`, Date.now(), { code: { From 1167699ae656b02fc412555b1eee6ee2fa793606 Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Thu, 30 Apr 2020 12:40:26 +1000 Subject: [PATCH 8/9] chat-js: refactor unread message fetch --- pkg/interface/chat/src/js/components/chat.js | 88 ++++++++++---------- 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/pkg/interface/chat/src/js/components/chat.js b/pkg/interface/chat/src/js/components/chat.js index 9f5bf8a77d..ca84931fc3 100644 --- a/pkg/interface/chat/src/js/components/chat.js +++ b/pkg/interface/chat/src/js/components/chat.js @@ -23,6 +23,7 @@ function getNumPending(props) { } const ACTIVITY_TIMEOUT = 60000; // a minute +const DEFAULT_BACKLOG_SIZE = 300; function scrollIsAtTop(container) { if ((navigator.userAgent.includes("Safari") && @@ -93,9 +94,6 @@ export class ChatScreen extends Component { } componentDidMount() { - this.askForMessages(); - this.scrollToBottom(); - document.addEventListener("mousemove", this.handleActivity, false); document.addEventListener("mousedown", this.handleActivity, false); document.addEventListener("keypress", this.handleActivity, false); @@ -120,8 +118,9 @@ export class ChatScreen extends Component { if(this.activityTimeout) { clearTimeout(this.activityTimeout); - this.activityTimeout = setTimeout(this.setInactive, ACTIVITY_TIMEOUT); } + + this.activityTimeout = setTimeout(this.setInactive, ACTIVITY_TIMEOUT); } setInactive() { @@ -129,6 +128,39 @@ export class ChatScreen extends Component { this.setState({ active: false, scrollLocked: true }); } + receivedNewChat() { + const { props } = this; + this.hasAskedForMessages = false; + + this.unreadMarker = null; + this.scrolledToMarker = false; + + this.setState({ read: props.read }); + + const unread = props.length - props.read; + const unreadUnloaded = unread - props.envelopes.length; + + if(unreadUnloaded + 20 > DEFAULT_BACKLOG_SIZE) { + this.askForMessages(unreadUnloaded + 20); + } else { + this.askForMessages(DEFAULT_BACKLOG_SIZE); + } + + if(props.read === props.length){ + this.scrolledToMarker = true; + this.setState( + { + scrollLocked: false, + }, + () => { + this.scrollToBottom(); + } + ); + } else { + this.setState({ scrollLocked: true, numPages: Math.ceil(unread/100) }); + } + } + componentDidUpdate(prevProps, prevState) { const { props, state } = this; @@ -136,23 +168,7 @@ export class ChatScreen extends Component { prevProps.match.params.station !== props.match.params.station || prevProps.match.params.ship !== props.match.params.ship ) { - this.hasAskedForMessages = false; - - if (props.envelopes.length < 100) { - this.askForMessages(); - } - - this.unreadMarker = null; - this.scrolledToMarker = false; - this.setState( - { - scrollLocked: false, - read: props.read, - }, - () => { - this.scrollToBottom(); - } - ); + this.receivedNewChat(); } else if (props.chatInitialized && !(props.station in props.inbox) && (!!props.chatSynced && !(props.station in props.chatSynced))) { @@ -163,15 +179,15 @@ export class ChatScreen extends Component { ) { this.hasAskedForMessages = false; } else if(props.length !== prevProps.length && - prevProps.length === prevProps.read && + prevProps.length === prevState.read && state.active ) { - this.setState({ read: props.length }) + this.setState({ read: props.length }); this.props.api.chat.read(this.props.station); } if(!prevProps.chatInitialized && props.chatInitialized) { - this.setState({ read: props.read }) + this.receivedNewChat(); } if ( @@ -189,16 +205,9 @@ export class ChatScreen extends Component { } } - askForMessages() { + askForMessages(size) { const { props, state } = this; - if (props.envelopes.length === 0) { - setTimeout(() => { - this.askForMessages(); - }, 500); - return; - } - if ( props.envelopes.length >= props.length || this.hasAskedForMessages || @@ -210,16 +219,8 @@ export class ChatScreen extends Component { let start = props.length - props.envelopes[props.envelopes.length - 1].number; if (start > 0) { - const unread = props.length - props.read; - const unloadedUnread = unread - props.envelopes.length; - const willLoadUnread = unloadedUnread > 280; - const offset = willLoadUnread ? unloadedUnread + 20 : 300; - const end = start + offset < props.length ? start + offset : props.length; + const end = start + size < props.length ? start + size : props.length; this.hasAskedForMessages = true; - if(willLoadUnread) { - // ensure unread marker is visible - this.setState({ numPages: Math.ceil(unread / 100) }); - } props.subscription.fetchMessages(start + 1, end, props.station); } } @@ -260,7 +261,7 @@ export class ChatScreen extends Component { scrollLocked: true }, () => { - this.askForMessages(); + this.askForMessages(DEFAULT_BACKLOG_SIZE); } ); } else if (scrollIsAtBottom(e.target)) { @@ -276,7 +277,8 @@ export class ChatScreen extends Component { if(ref && !this.scrolledToMarker) { this.setState({ scrollLocked: true }, () => { ref.scrollIntoView({ block: 'center' }); - if(scrollIsAtBottom(ref.offsetParent)) { + if(ref.offsetParent && + scrollIsAtBottom(ref.offsetParent)) { this.dismissUnread(); this.setState({ numPages: 1, From 6fb41209cd2df1648ee0ab2ef299990ed16964ad Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Tue, 5 May 2020 16:17:45 +1000 Subject: [PATCH 9/9] chat: fix ship search not wrapping correctly fixes #2832 --- pkg/interface/chat/src/js/components/lib/ship-search.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/interface/chat/src/js/components/lib/ship-search.js b/pkg/interface/chat/src/js/components/lib/ship-search.js index 250fc0dcbf..f64ec894a6 100644 --- a/pkg/interface/chat/src/js/components/lib/ship-search.js +++ b/pkg/interface/chat/src/js/components/lib/ship-search.js @@ -233,7 +233,7 @@ export class ShipSearch extends Component { let idx = suggestions.findIndex(s => s === this.state.selected); idx = backward ? idx - 1 : idx + 1; - idx = idx % suggestions.length; + idx = idx % Math.min(suggestions.length, 5); if (idx < 0) { idx = suggestions.length - 1; }