|
|
|
@ -22,12 +22,14 @@ interface State {
|
|
|
|
|
sendingProgess: number;
|
|
|
|
|
prevSendingProgess: number;
|
|
|
|
|
conversationKey: string;
|
|
|
|
|
unreadCount: number;
|
|
|
|
|
messages: Array<any>;
|
|
|
|
|
// Scroll position as percentage of message-list
|
|
|
|
|
scrollPositionPc: number;
|
|
|
|
|
// Scroll position in pixels
|
|
|
|
|
scrollPositionPx: number;
|
|
|
|
|
doneInitialScroll: boolean;
|
|
|
|
|
messageFetchTimestamp: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class SessionConversation extends React.Component<any, State> {
|
|
|
|
@ -35,16 +37,24 @@ export class SessionConversation extends React.Component<any, State> {
|
|
|
|
|
|
|
|
|
|
constructor(props: any) {
|
|
|
|
|
super(props);
|
|
|
|
|
|
|
|
|
|
const conversationKey = this.props.conversations.selectedConversation;
|
|
|
|
|
|
|
|
|
|
const conversation = this.props.conversations.conversationLookup[conversationKey];
|
|
|
|
|
const unreadCount = conversation.unreadCount;
|
|
|
|
|
|
|
|
|
|
console.log(`[vince][info] Conversation: `, conversation);
|
|
|
|
|
|
|
|
|
|
this.state = {
|
|
|
|
|
sendingProgess: 0,
|
|
|
|
|
prevSendingProgess: 0,
|
|
|
|
|
conversationKey,
|
|
|
|
|
unreadCount,
|
|
|
|
|
messages: [],
|
|
|
|
|
doneInitialScroll: false,
|
|
|
|
|
scrollPositionPc: 0,
|
|
|
|
|
scrollPositionPx: 0,
|
|
|
|
|
messageFetchTimestamp: 0,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
this.scrollToUnread = this.scrollToUnread.bind(this);
|
|
|
|
@ -60,7 +70,8 @@ export class SessionConversation extends React.Component<any, State> {
|
|
|
|
|
public async componentWillMount() {
|
|
|
|
|
const { conversationKey } = this.state;
|
|
|
|
|
await this.getMessages(conversationKey);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Inside a setTimeout to simultate onready()
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
this.scrollToBottom(true);
|
|
|
|
|
}, 0);
|
|
|
|
@ -74,7 +85,15 @@ export class SessionConversation extends React.Component<any, State> {
|
|
|
|
|
|
|
|
|
|
public async componentWillReceiveProps() {
|
|
|
|
|
const { conversationKey } = this.state;
|
|
|
|
|
await this.getMessages(conversationKey);
|
|
|
|
|
const timestamp = this.getTimestamp();
|
|
|
|
|
|
|
|
|
|
// If we have pulled messages in the last second, don't bother rescanning
|
|
|
|
|
// This avoids getting messages on every re-render.
|
|
|
|
|
if (timestamp > this.state.messageFetchTimestamp) {
|
|
|
|
|
await this.getMessages(conversationKey);
|
|
|
|
|
} else{
|
|
|
|
|
console.log(`[vince][info] Messages recieved in last second, stream`);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
render() {
|
|
|
|
@ -115,11 +134,11 @@ export class SessionConversation extends React.Component<any, State> {
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
<div className="messages-container">
|
|
|
|
|
{this.renderMessages(conversationKey)}
|
|
|
|
|
{this.renderMessages()}
|
|
|
|
|
<div ref={this.messagesEndRef} />
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<SessionScrollButton display={true} onClick={this.scrollToBottom}/>
|
|
|
|
|
<SessionScrollButton display={true} onClick={this.scrollToUnread}/>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
@ -208,20 +227,13 @@ export class SessionConversation extends React.Component<any, State> {
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public scrollToUnread() {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public scrollToBottom(firstLoad = false) {
|
|
|
|
|
this.messagesEndRef.current?.scrollIntoView(
|
|
|
|
|
{ behavior: firstLoad ? 'auto' : 'smooth' }
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async getMessages(conversationKey: string, limit = window.CONSTANTS.DEFAULT_MESSAGE_FETCH_COUNT){
|
|
|
|
|
public async getMessages(conversationKey: string){
|
|
|
|
|
const msgCount = window.CONSTANTS.DEFAULT_MESSAGE_FETCH_COUNT + this.state.unreadCount;
|
|
|
|
|
|
|
|
|
|
const messageSet = await window.Signal.Data.getMessagesByConversation(
|
|
|
|
|
conversationKey,
|
|
|
|
|
{ limit, MessageCollection: window.Whisper.MessageCollection },
|
|
|
|
|
{ msgCount, MessageCollection: window.Whisper.MessageCollection },
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Set first member of series here.
|
|
|
|
@ -229,17 +241,20 @@ export class SessionConversation extends React.Component<any, State> {
|
|
|
|
|
let messages = [];
|
|
|
|
|
let previousSender;
|
|
|
|
|
for (let i = 0; i < messageModels.length; i++){
|
|
|
|
|
// Handle firstMessageOfSeries for conditional avatar rendering
|
|
|
|
|
let firstMessageOfSeries = true;
|
|
|
|
|
if (i > 0 && previousSender === messageModels[i].authorPhoneNumber){
|
|
|
|
|
firstMessageOfSeries = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
messages.push({...messageModels[i], firstMessageOfSeries});
|
|
|
|
|
previousSender = messageModels[i].authorPhoneNumber;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
console.log(`[vince][messages] Messages`, messages);
|
|
|
|
|
|
|
|
|
|
this.setState({ messages });
|
|
|
|
|
const messageFetchTimestamp = this.getTimestamp();
|
|
|
|
|
|
|
|
|
|
console.log(`[vince][messages] Messages Set`, messageModels);
|
|
|
|
|
this.setState({ messages, messageFetchTimestamp });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public renderMessage(messageProps: any, firstMessageOfSeries: boolean, quoteProps?: any) {
|
|
|
|
@ -326,5 +341,27 @@ export class SessionConversation extends React.Component<any, State> {
|
|
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public getTimestamp() {
|
|
|
|
|
return Math.floor(Date.now() / 1000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public handleScroll() {
|
|
|
|
|
// Update unread count
|
|
|
|
|
|
|
|
|
|
// Get id of message at bottom of screen in full view. This is scroll position by messageID
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public scrollToUnread() {
|
|
|
|
|
const topUnreadMessage = document.getElementById('70fd6220-5292-43d8-9e0d-f98bf4792f43');
|
|
|
|
|
topUnreadMessage?.scrollIntoView(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public scrollToBottom(firstLoad = false) {
|
|
|
|
|
this.messagesEndRef.current?.scrollIntoView(
|
|
|
|
|
{ behavior: firstLoad ? 'auto' : 'smooth' }
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|