diff --git a/pkg/interface/src/views/apps/chat/components/lib/ChatMessage.tsx b/pkg/interface/src/views/apps/chat/components/lib/ChatMessage.tsx
index 30ab082f9..3c87a08aa 100644
--- a/pkg/interface/src/views/apps/chat/components/lib/ChatMessage.tsx
+++ b/pkg/interface/src/views/apps/chat/components/lib/ChatMessage.tsx
@@ -1,6 +1,7 @@
import React, { Component, PureComponent } from "react";
import moment from "moment";
import _ from "lodash";
+import { Box } from "@tlon/indigo-react";
import { OverlaySigil } from './overlay-sigil';
import { uxToHex, cite, writeText } from '~/logic/lib/util';
@@ -12,14 +13,10 @@ import RemoteContent from '~/views/components/RemoteContent';
export const DATESTAMP_FORMAT = '[~]YYYY.M.D';
-export const UnreadMarker = React.forwardRef(({ dayBreak, when, style }, ref) => (
-
{
- setTimeout(() => {
- element.style.opacity = '1';
- }, 250);
- }} className="green2 flex items-center f9 absolute w-100" style={{...style, opacity: '0'}}>
+export const UnreadMarker = React.forwardRef(({ dayBreak, when }, ref) => (
+
-
New messages below
+
New messages below
{dayBreak
?
{moment(when).calendar()}
@@ -39,18 +36,19 @@ interface ChatMessageProps {
msg: Envelope | IMessage;
previousMsg: Envelope | IMessage | undefined;
nextMsg: Envelope | IMessage | undefined;
- isFirstUnread: boolean;
+ isLastRead: boolean;
group: Group;
association: Association;
contacts: Contacts;
- unreadRef: React.RefObject
;
hideAvatars: boolean;
hideNicknames: boolean;
remoteContentPolicy: LocalUpdateRemoteContentPolicy;
- className: string;
+ className?: string;
isPending: boolean;
style?: any;
scrollWindow: HTMLDivElement;
+ isLastMessage?: boolean;
+ unreadMarkerRef: React.RefObject;
}
export default class ChatMessage extends Component {
@@ -72,11 +70,10 @@ export default class ChatMessage extends Component {
msg,
previousMsg,
nextMsg,
- isFirstUnread,
+ isLastRead,
group,
association,
contacts,
- unreadRef,
hideAvatars,
hideNicknames,
remoteContentPolicy,
@@ -84,7 +81,9 @@ export default class ChatMessage extends Component {
isPending,
style,
measure,
- scrollWindow
+ scrollWindow,
+ isLastMessage,
+ unreadMarkerRef
} = this.props;
const renderSigil = Boolean((nextMsg && msg.author !== nextMsg.author) || !nextMsg || msg.number === 1);
@@ -92,7 +91,7 @@ export default class ChatMessage extends Component {
const containerClass = `${renderSigil
? `w-100 flex flex-wrap cf pr3 f7 pt4 pl3 lh-copy`
- : `w-100 flex flex-wrap cf pr3 hide-child`} ${isPending ? ' o-40' : ''} ${className}`
+ : `w-100 flex flex-wrap cf pr3 hide-child`} ${isPending ? 'o-40' : ''} ${isLastMessage ? 'pb3' : ''} ${className}`
const timestamp = moment.unix(msg.when / 1000).format(renderSigil ? 'hh:mm a' : 'hh:mm');
@@ -116,15 +115,19 @@ export default class ChatMessage extends Component {
scrollWindow
};
+ const unreadContainerStyle = {
+ height: isLastRead ? '1.66em' : '0',
+ };
+
return (
- {dayBreak && !isFirstUnread ? : null}
+ {dayBreak && !isLastRead ? : null}
{renderSigil
?
: }
- {isFirstUnread
- ?
- : null}
+ {isLastRead
+ ?
+ : null}
);
}
diff --git a/pkg/interface/src/views/apps/chat/components/lib/ChatWindow.tsx b/pkg/interface/src/views/apps/chat/components/lib/ChatWindow.tsx
index 4724a94bf..bc3f9270b 100644
--- a/pkg/interface/src/views/apps/chat/components/lib/ChatWindow.tsx
+++ b/pkg/interface/src/views/apps/chat/components/lib/ChatWindow.tsx
@@ -48,10 +48,12 @@ interface ChatWindowState {
fetchPending: boolean;
idle: boolean;
initialized: boolean;
+ lastRead: number;
}
export default class ChatWindow extends Component {
private virtualList: VirtualScroller | null;
+ private unreadMarkerRef: React.RefObject;
INITIALIZATION_MAX_TIME = 1500;
@@ -61,18 +63,20 @@ export default class ChatWindow extends Component 0) {
@@ -112,17 +108,9 @@ export default class ChatWindow extends Component {
if (!this.virtualList) return;
- const initialIndex = this.initialIndex();
- this.virtualList.scrollToData(initialIndex).then(() => {
- if (
- initialIndex === mailboxSize
- || (this.virtualList && this.virtualList.window && this.virtualList.window.scrollTop === 0)
- ) {
- this.setState({ idle: false });
- this.dismissUnread();
- }
- this.setState({ initialized: true });
- });
+ this.setState({ idle: false });
+ this.setState({ initialized: true });
+ this.dismissIfLineVisible();
});
} else {
setTimeout(() => {
@@ -195,9 +183,31 @@ export default class ChatWindow extends Component IDLE_THRESHOLD) {
+ this.setState({ idle: true });
+ }
+
+ this.dismissIfLineVisible();
+ }
+
+ dismissIfLineVisible() {
+ if (this.props.unreadCount === 0) return;
+ if (!this.unreadMarkerRef.current || !this.virtualList?.window) return;
+ const parent = this.unreadMarkerRef.current.parentElement?.parentElement;
+ if (!parent) return;
+ const { scrollTop, scrollHeight, offsetHeight } = this.virtualList.window;
+ if (
+ (scrollHeight - parent.offsetTop > scrollTop)
+ && (scrollHeight - parent.offsetTop < scrollTop + offsetHeight)
+ ) {
+ this.dismissUnread();
+ }
}
render() {
@@ -220,6 +230,8 @@ export default class ChatWindow extends Component
@@ -258,11 +270,7 @@ export default class ChatWindow extends Component {
- if (!this.state.idle && scrollTop > IDLE_THRESHOLD) {
- this.setState({ idle: true });
- }
- }}
+ onScroll={this.onScroll.bind(this)}
data={messages}
size={mailboxSize + stationPendingMessages.length}
renderer={({ index, measure, scrollWindow }) => {
@@ -272,15 +280,14 @@ export default class ChatWindow extends Component;
}
const isPending: boolean = 'pending' in msg && Boolean(msg.pending);
- const isFirstUnread: boolean = Boolean(unreadCount && index === this.firstUnread());
const isLastMessage: boolean = Boolean(index === lastMessage)
- const props = { measure, scrollWindow, isPending, isFirstUnread, msg, ...messageProps };
+ const isLastRead: boolean = Boolean(!isLastMessage && index === this.state.lastRead);
+ const props = { measure, scrollWindow, isPending, isLastRead, isLastMessage, msg, ...messageProps };
return (
);