Scrolling

pull/1102/head
Vincent 5 years ago
parent af29113fab
commit d662fcfa1a

@ -1497,9 +1497,11 @@ input {
} }
} }
.module-scroll-down { .session-scroll-button {
animation: fadein $session-fadein-duration; animation: fadein $session-fadein-duration;
position: absolute;
bottom: 15px; bottom: 15px;
right: 25px;
.session-icon-button { .session-icon-button {
display: flex; display: flex;
@ -1510,7 +1512,7 @@ input {
border-radius: 50%; border-radius: 50%;
opacity: 1; opacity: 1;
background-color: $session-shade-2; background-color: $session-shade-2;
box-shadow: 0px 0px $session-font-sm 0px rgba($session-color-white, 0.1); box-shadow: 0px 0px $session-font-sm 0px rgba($session-color-white, 0.2);
svg path { svg path {
transition: $session-transition-duration; transition: $session-transition-duration;

@ -14,15 +14,30 @@ $composition-container-height: 60px;
background-color: $session-shade-2; background-color: $session-shade-2;
} }
.messages-wrapper {
display: flex;
flex-grow: 1;
flex-direction: column;
position: relative;
}
.messages-container { .messages-container {
display: flex; display: flex;
flex-grow: 1; flex-grow: 1;
flex-direction: column; flex-direction: column;
position: relative;
overflow-y: auto; overflow-y: auto;
scrollbar-width: 4px; scrollbar-width: 4px;
padding: $session-margin-lg; padding: $session-margin-lg;
scroll-behavior: smooth;
&__loading { &__loading {
position: absolute;
top: 0px;
right: 0px;
left: 0px;
bottom: 0px;
z-index: 100;
background-color: $session-shade-2;
display: flex; display: flex;
flex-grow: 1; flex-grow: 1;
align-items: center; align-items: center;

@ -1,4 +1,4 @@
import React from 'react'; import React, { useEffect, useRef } from 'react';
import { ConversationHeader } from '../conversation/ConversationHeader'; import { ConversationHeader } from '../conversation/ConversationHeader';
import { SessionCompositionBox } from './SessionCompositionBox'; import { SessionCompositionBox } from './SessionCompositionBox';
@ -6,7 +6,8 @@ import { SessionProgress } from './SessionProgress'
import { Message } from '../conversation/Message'; import { Message } from '../conversation/Message';
import { SessionSpinner } from './SessionSpinner'; import { SessionSpinner } from './SessionSpinner';
import { configure } from 'protobufjs'; import { SessionScrollButton } from './SessionScrollButton';
// interface Props { // interface Props {
@ -19,28 +20,54 @@ interface State {
prevSendingProgess: number; prevSendingProgess: number;
conversationKey: string; conversationKey: string;
messages: Array<any>; messages: Array<any>;
// Scroll position as percentage of message-list
scrollPositionPc: number;
// Scroll position in pixels
scrollPositionPx: number;
doneInitialScroll: boolean;
} }
export class SessionConversation extends React.Component<any, State> { export class SessionConversation extends React.Component<any, State> {
private messagesEndRef: React.RefObject<HTMLDivElement>;
constructor(props: any) { constructor(props: any) {
super(props); super(props);
const conversationKey = this.props.conversations.selectedConversation; const conversationKey = this.props.conversations.selectedConversation;
const messages = this.props.conversations.conversationLookup[conversationKey].messages;
this.state = { this.state = {
sendingProgess: 0, sendingProgess: 0,
prevSendingProgess: 0, prevSendingProgess: 0,
conversationKey, conversationKey,
messages: [], messages,
doneInitialScroll: false,
scrollPositionPc: 0,
scrollPositionPx: 0,
}; };
this.scrollToUnread = this.scrollToUnread.bind(this);
this.scrollToBottom = this.scrollToBottom.bind(this);
this.messagesEndRef = React.createRef();
} }
public async componentWillUpdate () { public componentDidMount() {
setTimeout(() => {
this.scrollToBottom(true);
}, 20);
this.setState({
doneInitialScroll: true,
});
}
public componentWillUpdate () {
console.log(`[vince][update] State:`, this.state); console.log(`[vince][update] State:`, this.state);
console.log(`[vince][update] Props:`, this.props); console.log(`[vince][update] Props:`, this.props);
} }
public async componentWillReceiveProps() { public componentWillReceiveProps() {
const { conversationKey, messages } = this.state; const { conversationKey, messages } = this.state;
const conversation = this.props.conversations.conversationLookup[conversationKey]; const conversation = this.props.conversations.conversationLookup[conversationKey];
@ -53,12 +80,16 @@ export class SessionConversation extends React.Component<any, State> {
console.log(`[vince][update] Should Update: `, shouldLoad) console.log(`[vince][update] Should Update: `, shouldLoad)
console.log(`[vince][update] called ComponentWillRevieceProps. Messages: `, this.state.messages) console.log(`[vince][update] called ComponentWillRevieceProps. Messages: `, this.state.messages)
if (conversationKey && shouldLoad){ // if (conversationKey && shouldLoad){
this.setState({ // this.setState({
messages: await window.getMessagesByKey(conversationKey, true) // messages: await window.getMessagesByKey(conversationKey, true)
}); // });
} // }
// this.setState({
// messages: this.props.conversations.conversationLookup[conversationKey]?.messsages,
// });
} }
render() { render() {
@ -66,9 +97,10 @@ export class SessionConversation extends React.Component<any, State> {
console.log(`[vince] These are SessionConversation props: `, this.props); console.log(`[vince] These are SessionConversation props: `, this.props);
// const headerProps = this.props.getHeaderProps; // const headerProps = this.props.getHeaderProps;
const { conversationKey } = this.state; const { messages, conversationKey, doneInitialScroll } = this.state;
const loadingMessages = this.state.messages.length === 0; const loading = !doneInitialScroll
console.log(`[vince] Loading: `, loading);
console.log(`[vince] My conversation key is: `, conversationKey); console.log(`[vince] My conversation key is: `, conversationKey);
// TMEPORARY SOLUTION TO GETTING CONVERSATION UNTIL // TMEPORARY SOLUTION TO GETTING CONVERSATION UNTIL
@ -79,7 +111,7 @@ export class SessionConversation extends React.Component<any, State> {
const conversationType = conversation.type; const conversationType = conversation.type;
return ( return (
<div className={`conversation-item conversation-${conversation.cid}`}> <div className="conversation-item">
<div className="conversation-header"> <div className="conversation-header">
{this.renderHeader(conversation)} {this.renderHeader(conversation)}
</div> </div>
@ -90,16 +122,21 @@ export class SessionConversation extends React.Component<any, State> {
prevValue={this.state.prevSendingProgess} prevValue={this.state.prevSendingProgess}
/> />
<div className="messages-container"> <div className="messages-wrapper">
{ loadingMessages ? ( { loading && (
<div className="messages-container__loading"> <div className="messages-container__loading">
<SessionSpinner/> <SessionSpinner/>
</div> </div>
) : (
<>
{this.renderMessages(conversationKey, conversationType)}
</>
)} )}
<div className="messages-container">
{this.renderMessages(conversationKey, conversationType)}
<div ref={this.messagesEndRef} />
</div>
<SessionScrollButton display={true} onClick={this.scrollToBottom}/>
</div> </div>
<SessionCompositionBox <SessionCompositionBox
@ -111,8 +148,8 @@ export class SessionConversation extends React.Component<any, State> {
public renderMessages(conversationKey: string, conversationType: 'group' | 'direct') { public renderMessages(conversationKey: string, conversationType: 'group' | 'direct') {
const { messages } = this.state; const { messages } = this.state;
console.log(`Messages`, messages); console.log(`[vince][messages]`, messages);
// FIND FOR EACH MESSAGE // FIND FOR EACH MESSAGE
const isExpired = false; const isExpired = false;
@ -209,7 +246,9 @@ export class SessionConversation extends React.Component<any, State> {
} }
public scrollToBottom() { public scrollToBottom(firstLoad = false) {
this.messagesEndRef.current?.scrollIntoView(
{ behavior: firstLoad ? 'auto' : 'smooth' }
);
} }
} }

@ -2,18 +2,30 @@ import React from 'react';
import { SessionIconButton, SessionIconSize, SessionIconType } from './icon'; import { SessionIconButton, SessionIconSize, SessionIconType } from './icon';
export class SessionScrollButton extends React.PureComponent { interface Props {
onClick?: any;
display?: boolean;
}
export class SessionScrollButton extends React.PureComponent<Props> {
constructor(props: any) { constructor(props: any) {
super(props); super(props);
} }
public render() { public render() {
return ( return (
<SessionIconButton <>
iconType={SessionIconType.Chevron} { this.props.display && (
iconSize={SessionIconSize.Huge} <div className="session-scroll-button">
iconColor={'#FFFFFF'} <SessionIconButton
/> iconType={SessionIconType.Chevron}
iconSize={SessionIconSize.Huge}
iconColor={'#FFFFFF'}
onClick={this.props.onClick}
/>
</div>
)}
</>
); );
} }
} }

Loading…
Cancel
Save