Upgrade typescript, finding messaages
							parent
							
								
									2c5e2df817
								
							
						
					
					
						commit
						ea4dc05009
					
				@ -1,69 +1,102 @@
 | 
			
		||||
$composition-container-height: 60px;
 | 
			
		||||
 | 
			
		||||
.conversation-item {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-grow: 1;
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
    height: 100%;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-grow: 1;
 | 
			
		||||
  flex-direction: column;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.session-conversation-wrapper {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    height: 100%;
 | 
			
		||||
    background-color: $session-shade-2;
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  background-color: $session-shade-2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.messages-container{
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-grow: 1;
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
.messages-container {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-grow: 1;
 | 
			
		||||
  flex-direction: column;
 | 
			
		||||
  padding: $session-margin-lg;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.composition-container {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  justify-content: center;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  background-color: $session-shade-4;
 | 
			
		||||
  padding: 0px $session-margin-md;
 | 
			
		||||
  min-height: $composition-container-height;
 | 
			
		||||
 | 
			
		||||
  & > .session-icon-button {
 | 
			
		||||
    margin-right: $session-margin-sm;
 | 
			
		||||
  }
 | 
			
		||||
  .session-icon-button {
 | 
			
		||||
    opacity: 0.8;
 | 
			
		||||
 | 
			
		||||
    .send {
 | 
			
		||||
      background-color: $session-shade-14;
 | 
			
		||||
      padding: $session-margin-xs;
 | 
			
		||||
      border-radius: 50%;
 | 
			
		||||
      height: 30px;
 | 
			
		||||
      width: 30px;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .send-message-input {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    justify-content: center;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    background-color: $session-shade-4;
 | 
			
		||||
    padding: 0px $session-margin-md;
 | 
			
		||||
    flex-grow: 1;
 | 
			
		||||
    min-height: $composition-container-height;
 | 
			
		||||
    
 | 
			
		||||
    & > .session-icon-button {
 | 
			
		||||
        margin-right: $session-margin-sm;
 | 
			
		||||
    }
 | 
			
		||||
    .session-icon-button {
 | 
			
		||||
        opacity: 0.8;
 | 
			
		||||
            
 | 
			
		||||
        .send {
 | 
			
		||||
            background-color: $session-shade-14;
 | 
			
		||||
            padding: $session-margin-xs;
 | 
			
		||||
            border-radius: 50%;
 | 
			
		||||
            height: 30px;
 | 
			
		||||
            width: 30px;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    .send-message-input {
 | 
			
		||||
    padding: $composition-container-height / 3 0px;
 | 
			
		||||
 | 
			
		||||
    textarea {
 | 
			
		||||
      font-family: 'SF Pro Text';
 | 
			
		||||
      min-height: $composition-container-height / 3;
 | 
			
		||||
      max-height: 2 * $composition-container-height;
 | 
			
		||||
      margin-right: $session-margin-md;
 | 
			
		||||
      color: $session-color-white;
 | 
			
		||||
      resize: none;
 | 
			
		||||
      display: flex;
 | 
			
		||||
      flex-grow: 1;
 | 
			
		||||
      min-height: $composition-container-height
 | 
			
		||||
        
 | 
			
		||||
      textarea {
 | 
			
		||||
        min-height: $composition-container-height / 3;
 | 
			
		||||
        max-height: 3 * $composition-container-height;
 | 
			
		||||
        margin-right: $session-margin-md;
 | 
			
		||||
        color: $session-color-white;
 | 
			
		||||
        resize: none;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        flex-grow: 1;
 | 
			
		||||
        background: transparent;
 | 
			
		||||
        outline: none;
 | 
			
		||||
        border: none;
 | 
			
		||||
        font-size: $session-font-md;
 | 
			
		||||
        line-height: $session-font-h2;
 | 
			
		||||
        padding: $composition-container-height / 3 0px;
 | 
			
		||||
        
 | 
			
		||||
      }
 | 
			
		||||
      background: transparent;
 | 
			
		||||
      outline: none;
 | 
			
		||||
      border: none;
 | 
			
		||||
      font-size: $session-font-md;
 | 
			
		||||
      line-height: $session-font-h2;
 | 
			
		||||
      letter-spacing: 0.5px;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.session-emoji-panel {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
    bottom: 68px;
 | 
			
		||||
    right: 0px;
 | 
			
		||||
    min-height: 400px;
 | 
			
		||||
    min-width: 400px;
 | 
			
		||||
    background-color: $session-shade-4;
 | 
			
		||||
    border: 1px solid $session-shade-6;
 | 
			
		||||
    border-top-right-radius: 3px;
 | 
			
		||||
    border-top-left-radius: 3px;
 | 
			
		||||
    padding: $session-margin-lg;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.session-progress {
 | 
			
		||||
  position: relative;
 | 
			
		||||
  background-color: rgba(30, 30, 30, 0.5);
 | 
			
		||||
 | 
			
		||||
  &__progress {
 | 
			
		||||
    transition: opacity 0.15s;
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    left: 0px;
 | 
			
		||||
    font-size: 0px;
 | 
			
		||||
    height: 3px;
 | 
			
		||||
 | 
			
		||||
    background-color: $session-color-green;
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,85 @@
 | 
			
		||||
import React from 'react';
 | 
			
		||||
 | 
			
		||||
import TextareaAutosize from 'react-autosize-textarea';
 | 
			
		||||
import { SessionIconButton, SessionIconSize, SessionIconType } from './icon';
 | 
			
		||||
import { SessionEmojiPanel } from './SessionEmojiPanel';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
interface Props {
 | 
			
		||||
  placeholder?: string;
 | 
			
		||||
  onSendMessage: any;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface State {
 | 
			
		||||
    message: string;
 | 
			
		||||
    showEmojiPanel: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class SessionCompositionBox extends React.Component<Props, State> {
 | 
			
		||||
  private textarea: React.RefObject<HTMLTextAreaElement>;
 | 
			
		||||
 | 
			
		||||
  constructor(props: any) {
 | 
			
		||||
    super(props);
 | 
			
		||||
 | 
			
		||||
    this.state = {
 | 
			
		||||
        message: '',
 | 
			
		||||
        showEmojiPanel: false,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    this.textarea = React.createRef();
 | 
			
		||||
    this.toggleEmojiPanel = this.toggleEmojiPanel.bind(this);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  render() {
 | 
			
		||||
    const { placeholder } = this.props;
 | 
			
		||||
    const { showEmojiPanel } = this.state;
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
      <div className="composition-container">
 | 
			
		||||
        <SessionIconButton
 | 
			
		||||
          iconType={SessionIconType.CirclePlus}
 | 
			
		||||
          iconSize={SessionIconSize.Large}
 | 
			
		||||
        />
 | 
			
		||||
        <SessionIconButton
 | 
			
		||||
          iconType={SessionIconType.Microphone}
 | 
			
		||||
          iconSize={SessionIconSize.Large}
 | 
			
		||||
        />
 | 
			
		||||
 | 
			
		||||
        <div className="send-message-input">
 | 
			
		||||
          <TextareaAutosize
 | 
			
		||||
            rows={1}
 | 
			
		||||
            maxRows={6}
 | 
			
		||||
            ref={this.textarea}
 | 
			
		||||
            placeholder={placeholder}
 | 
			
		||||
            maxLength={window.CONSTANTS.MAX_MESSAGE_BODY_LENGTH}
 | 
			
		||||
          />
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <SessionIconButton
 | 
			
		||||
          iconType={SessionIconType.Emoji}
 | 
			
		||||
          iconSize={SessionIconSize.Large}
 | 
			
		||||
          onClick={this.toggleEmojiPanel}
 | 
			
		||||
        />
 | 
			
		||||
        <div className="send-message-button">
 | 
			
		||||
          <SessionIconButton
 | 
			
		||||
            iconType={SessionIconType.Send}
 | 
			
		||||
            iconSize={SessionIconSize.Large}
 | 
			
		||||
            iconColor={'#FFFFFF'}
 | 
			
		||||
            iconRotation={90}
 | 
			
		||||
          />
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        { showEmojiPanel && 
 | 
			
		||||
          ( <SessionEmojiPanel/> )
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      </div>
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public toggleEmojiPanel() {
 | 
			
		||||
    this.setState({
 | 
			
		||||
      showEmojiPanel: !this.state.showEmojiPanel,
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -1,120 +1,218 @@
 | 
			
		||||
import React from 'react';
 | 
			
		||||
 | 
			
		||||
import TextareaAutosize from 'react-autosize-textarea';
 | 
			
		||||
 | 
			
		||||
import { ConversationHeader } from '../conversation/ConversationHeader';
 | 
			
		||||
import { SessionIconButton, SessionIconSize, SessionIconType } from './icon';
 | 
			
		||||
import { SessionCompositionBox } from './SessionCompositionBox';
 | 
			
		||||
import { SessionProgress } from './SessionProgress'
 | 
			
		||||
 | 
			
		||||
import { Message } from '../conversation/Message';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
interface Props {
 | 
			
		||||
  getHeaderProps: any;
 | 
			
		||||
  conversationKey: any;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface State {
 | 
			
		||||
  sendingProgess: number;
 | 
			
		||||
  prevSendingProgess: number;
 | 
			
		||||
  loadingMessages: boolean;
 | 
			
		||||
  messages: any;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class SessionConversation extends React.Component<Props, State> {
 | 
			
		||||
  constructor(props: any) {
 | 
			
		||||
    super(props);
 | 
			
		||||
    this.state = {
 | 
			
		||||
      sendingProgess: 0,
 | 
			
		||||
      prevSendingProgess: 0,
 | 
			
		||||
      loadingMessages: false,
 | 
			
		||||
      messages: {},
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
interface Props{
 | 
			
		||||
    getHeaderProps: any;
 | 
			
		||||
  async componentWillMount() {
 | 
			
		||||
    const { conversationKey } = this.props;
 | 
			
		||||
 | 
			
		||||
    this.setState({
 | 
			
		||||
      messages: await window.getMessagesByKey(conversationKey)
 | 
			
		||||
    })
 | 
			
		||||
    
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
interface State{};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export class SessionConversation extends React.Component<Props, State> {    
 | 
			
		||||
    constructor(props: any) {
 | 
			
		||||
        super(props);
 | 
			
		||||
        this.state = {};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    render() {
 | 
			
		||||
        // const headerProps = this.props.getHeaderProps;
 | 
			
		||||
 | 
			
		||||
        // TMEPORARY SOLUTION TO GETTING CONVERSATION UNTIL
 | 
			
		||||
        // SessionConversationStack is created
 | 
			
		||||
        const conversation = window.getConversations().models[0];
 | 
			
		||||
 | 
			
		||||
        return (
 | 
			
		||||
            <div className={`conversation-item conversation-${conversation.cid}`}>
 | 
			
		||||
 | 
			
		||||
                <div className="conversation-header">
 | 
			
		||||
                    {this.renderHeader(conversation)}
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
                <div className="messages-container">
 | 
			
		||||
                    THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW 
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
                <div className="composition-container">
 | 
			
		||||
                    <SessionIconButton
 | 
			
		||||
                        iconType={SessionIconType.CirclePlus}
 | 
			
		||||
                        iconSize={SessionIconSize.Large}
 | 
			
		||||
                    />
 | 
			
		||||
                    <SessionIconButton
 | 
			
		||||
                        iconType={SessionIconType.Microphone}
 | 
			
		||||
                        iconSize={SessionIconSize.Large}
 | 
			
		||||
                    />
 | 
			
		||||
 | 
			
		||||
                    <div className="send-message-input">
 | 
			
		||||
                        <TextareaAutosize
 | 
			
		||||
                            rows={1}
 | 
			
		||||
                            maxRows={6}
 | 
			
		||||
                        />
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <SessionIconButton
 | 
			
		||||
                        iconType={SessionIconType.Emoji}
 | 
			
		||||
                        iconSize={SessionIconSize.Large}
 | 
			
		||||
                    />
 | 
			
		||||
                    <div className="send-message-button">
 | 
			
		||||
                        <SessionIconButton
 | 
			
		||||
                            iconType={SessionIconType.Send}
 | 
			
		||||
                            iconSize={SessionIconSize.Large}
 | 
			
		||||
                            iconColor={'#FFFFFF'}
 | 
			
		||||
                            iconRotation={90}
 | 
			
		||||
                        />
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    renderHeader(conversation: any) {
 | 
			
		||||
        return (
 | 
			
		||||
          <ConversationHeader
 | 
			
		||||
            id={conversation.cid}
 | 
			
		||||
            phoneNumber={conversation.id}
 | 
			
		||||
            isVerified={true}
 | 
			
		||||
            isMe={false}
 | 
			
		||||
            isFriend={true}
 | 
			
		||||
            i18n={window.i18n}
 | 
			
		||||
            isGroup={false}
 | 
			
		||||
            isArchived={false}
 | 
			
		||||
            isPublic={false}
 | 
			
		||||
            isRss={false}
 | 
			
		||||
            amMod={false}
 | 
			
		||||
            members={[]}
 | 
			
		||||
            showBackButton={false}
 | 
			
		||||
            timerOptions={[]}
 | 
			
		||||
            isBlocked={false}
 | 
			
		||||
            hasNickname={false}
 | 
			
		||||
            isFriendRequestPending={false}
 | 
			
		||||
            isOnline={true}
 | 
			
		||||
            selectedMessages={null}
 | 
			
		||||
            onSetDisappearingMessages={() => null}
 | 
			
		||||
            onDeleteMessages={() => null}
 | 
			
		||||
            onDeleteContact={() => null}
 | 
			
		||||
            onResetSession={() => null}
 | 
			
		||||
            onCloseOverlay={() => null}
 | 
			
		||||
            onDeleteSelectedMessages={() => null}
 | 
			
		||||
            onArchive={() => null}
 | 
			
		||||
            onMoveToInbox={() => null}
 | 
			
		||||
            onShowSafetyNumber={() => null}
 | 
			
		||||
            onShowAllMedia={() => null}
 | 
			
		||||
            onShowGroupMembers={() => null}
 | 
			
		||||
            onGoBack={() => null}
 | 
			
		||||
            onBlockUser={() => null}
 | 
			
		||||
            onUnblockUser={() => null}
 | 
			
		||||
            onClearNickname={() => null}
 | 
			
		||||
            onChangeNickname={() => null}
 | 
			
		||||
            onCopyPublicKey={() => null}
 | 
			
		||||
            onLeaveGroup={() => null}
 | 
			
		||||
            onAddModerators={() => null}
 | 
			
		||||
            onRemoveModerators={() => null}
 | 
			
		||||
            onInviteFriends={() => null}
 | 
			
		||||
          />
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  render() {
 | 
			
		||||
    // const headerProps = this.props.getHeaderProps;
 | 
			
		||||
    const { conversationKey } = this.props;
 | 
			
		||||
 | 
			
		||||
    // TMEPORARY SOLUTION TO GETTING CONVERSATION UNTIL
 | 
			
		||||
    // SessionConversationStack is created
 | 
			
		||||
 | 
			
		||||
    // Get conversation by Key (NOT cid)
 | 
			
		||||
    const conversation = window.getConversationByKey(conversationKey);
 | 
			
		||||
 | 
			
		||||
    console.log(`Conversation key: `, conversationKey);
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
      <div className={`conversation-item conversation-${conversation.cid}`}>
 | 
			
		||||
        <div className="conversation-header">
 | 
			
		||||
          {this.renderHeader(conversation)}
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <SessionProgress
 | 
			
		||||
          visible={true}
 | 
			
		||||
          value={this.state.sendingProgess}
 | 
			
		||||
          prevValue={this.state.prevSendingProgess}
 | 
			
		||||
        />
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        <div className="messages-container">
 | 
			
		||||
          {this.renderMessages(conversationKey)}
 | 
			
		||||
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <SessionCompositionBox
 | 
			
		||||
            onSendMessage={() => null}
 | 
			
		||||
        />
 | 
			
		||||
      </div>
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public renderMessages(conversationKey: string ) {
 | 
			
		||||
    const { messages } = this.state;
 | 
			
		||||
 | 
			
		||||
    // FIXME PAY ATTENTION; ONLY RENDER MESSAGES THAT ARE VISIBLE
 | 
			
		||||
    const messagesLength = messages.length;
 | 
			
		||||
 | 
			
		||||
    console.log(`Messages`, messages);
 | 
			
		||||
 | 
			
		||||
    let messageList = [];
 | 
			
		||||
 | 
			
		||||
    messages?.keys.map(key => {
 | 
			
		||||
      const message = messages[key];
 | 
			
		||||
      return (<>THIS IS A MESSAGE</>)
 | 
			
		||||
    });
 | 
			
		||||
    console.log(messages);
 | 
			
		||||
 | 
			
		||||
    return messages;
 | 
			
		||||
 | 
			
		||||
    // for(let i = messagesLength - 1; i > 0; i--){
 | 
			
		||||
    //     messageList.push({
 | 
			
		||||
    //       isDeletable: true,
 | 
			
		||||
    //       text: 'fdgdfg',
 | 
			
		||||
    //       direction: 'incoming',
 | 
			
		||||
    //       timestamp: '1581565995228',
 | 
			
		||||
    //       i18n: window.i18n,
 | 
			
		||||
    //       authorPhoneNumber: messages[i].source,
 | 
			
		||||
    //       conversationType: 'direct',
 | 
			
		||||
    //       previews: [],
 | 
			
		||||
    //       isExpired: false, 
 | 
			
		||||
    //       convoId: messages[i].conversationId,
 | 
			
		||||
    //       selected: false,
 | 
			
		||||
    //       multiSelectMode: false,
 | 
			
		||||
    //       onSelectMessage: () => null,
 | 
			
		||||
    //       onSelectMessageUnchecked: () => null,
 | 
			
		||||
    //       onShowDetail : () => null,
 | 
			
		||||
    //       onShowUserDetails: () => null,
 | 
			
		||||
    //     });
 | 
			
		||||
    // }
 | 
			
		||||
 | 
			
		||||
    // console.log(`[vince] MessageList: `, messageList);
 | 
			
		||||
 | 
			
		||||
    // return messages && (
 | 
			
		||||
    //   <Message
 | 
			
		||||
    //     isDeletable = {false}
 | 
			
		||||
    //     text = {messages[0].body}
 | 
			
		||||
    //     direction = {'incoming'}
 | 
			
		||||
    //     timestamp = {1581565995228}
 | 
			
		||||
    //     i18n = {window.i18n}
 | 
			
		||||
    //     authorPhoneNumber = {messages[0].source}
 | 
			
		||||
    //     conversationType = {'direct'}
 | 
			
		||||
    //     previews = {[]}
 | 
			
		||||
    //     isExpired = {false}
 | 
			
		||||
    //     convoId = {messages[0].conversationId}
 | 
			
		||||
    //     selected = {false}
 | 
			
		||||
    //     multiSelectMode = {false}
 | 
			
		||||
    //     onSelectMessage = {() => null}
 | 
			
		||||
    //     onSelectMessageUnchecked = {() => null}
 | 
			
		||||
    //     onShowDetail = {() => null}
 | 
			
		||||
    //     onShowUserDetails = {() => null}
 | 
			
		||||
    //   />
 | 
			
		||||
    // )
 | 
			
		||||
 | 
			
		||||
    // return (
 | 
			
		||||
    //   <>
 | 
			
		||||
    //     {
 | 
			
		||||
    //       messageList.map(message => {
 | 
			
		||||
    //         return (
 | 
			
		||||
    //           <Message
 | 
			
		||||
    //             isDeletable = {message.isDeletable}
 | 
			
		||||
    //             text = {message.text}
 | 
			
		||||
    //             direction = {'incoming'}
 | 
			
		||||
    //             timestamp = {1581565995228}
 | 
			
		||||
    //             i18n = {message.i18n}
 | 
			
		||||
    //             authorPhoneNumber = {message.authorPhoneNumber}
 | 
			
		||||
    //             conversationType = {'direct'}
 | 
			
		||||
    //             previews = {message.previews}
 | 
			
		||||
    //             isExpired = {message.isExpired}
 | 
			
		||||
    //             convoId = {message.convoId}
 | 
			
		||||
    //             selected = {message.selected}
 | 
			
		||||
    //             multiSelectMode = {message.multiSelectMode}
 | 
			
		||||
    //             onSelectMessage = {message.onSelectMessage}
 | 
			
		||||
    //             onSelectMessageUnchecked = {message.onSelectMessageUnchecked}
 | 
			
		||||
    //             onShowDetail = {message.onShowDetail}
 | 
			
		||||
    //             onShowUserDetails = {message.onShowUserDetails}
 | 
			
		||||
    //           />
 | 
			
		||||
    //         )}
 | 
			
		||||
    //       );
 | 
			
		||||
    //     }
 | 
			
		||||
    //   </>
 | 
			
		||||
    // );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public renderHeader(conversation: any) {
 | 
			
		||||
    return (
 | 
			
		||||
      <ConversationHeader
 | 
			
		||||
        id={conversation.cid}
 | 
			
		||||
        phoneNumber={conversation.id}
 | 
			
		||||
        isVerified={true}
 | 
			
		||||
        isMe={false}
 | 
			
		||||
        isFriend={true}
 | 
			
		||||
        i18n={window.i18n}
 | 
			
		||||
        isGroup={false}
 | 
			
		||||
        isArchived={false}
 | 
			
		||||
        isPublic={false}
 | 
			
		||||
        isRss={false}
 | 
			
		||||
        amMod={false}
 | 
			
		||||
        members={[]}
 | 
			
		||||
        showBackButton={false}
 | 
			
		||||
        timerOptions={[]}
 | 
			
		||||
        isBlocked={false}
 | 
			
		||||
        hasNickname={false}
 | 
			
		||||
        isFriendRequestPending={false}
 | 
			
		||||
        isOnline={true}
 | 
			
		||||
        selectedMessages={null}
 | 
			
		||||
        onSetDisappearingMessages={() => null}
 | 
			
		||||
        onDeleteMessages={() => null}
 | 
			
		||||
        onDeleteContact={() => null}
 | 
			
		||||
        onResetSession={() => null}
 | 
			
		||||
        onCloseOverlay={() => null}
 | 
			
		||||
        onDeleteSelectedMessages={() => null}
 | 
			
		||||
        onArchive={() => null}
 | 
			
		||||
        onMoveToInbox={() => null}
 | 
			
		||||
        onShowSafetyNumber={() => null}
 | 
			
		||||
        onShowAllMedia={() => null}
 | 
			
		||||
        onShowGroupMembers={() => null}
 | 
			
		||||
        onGoBack={() => null}
 | 
			
		||||
        onBlockUser={() => null}
 | 
			
		||||
        onUnblockUser={() => null}
 | 
			
		||||
        onClearNickname={() => null}
 | 
			
		||||
        onChangeNickname={() => null}
 | 
			
		||||
        onCopyPublicKey={() => null}
 | 
			
		||||
        onLeaveGroup={() => null}
 | 
			
		||||
        onAddModerators={() => null}
 | 
			
		||||
        onRemoveModerators={() => null}
 | 
			
		||||
        onInviteFriends={() => null}
 | 
			
		||||
      />
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,29 @@
 | 
			
		||||
import React from 'react';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
interface Props {}
 | 
			
		||||
 | 
			
		||||
interface State {
 | 
			
		||||
  // FIXME Use Emoji-Mart categories
 | 
			
		||||
  category: null
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class SessionEmojiPanel extends React.Component<Props, State> {
 | 
			
		||||
 | 
			
		||||
  constructor(props: any) {
 | 
			
		||||
    super(props);
 | 
			
		||||
 | 
			
		||||
    this.state = {
 | 
			
		||||
      category: null,
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  render() {
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
      <div className='session-emoji-panel'>
 | 
			
		||||
        THIS IS EMOJI STUFF
 | 
			
		||||
      </div>
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,106 @@
 | 
			
		||||
import React from 'react';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
interface Props {
 | 
			
		||||
  // Value ranges from 0 to 100
 | 
			
		||||
  value: number;
 | 
			
		||||
  // Optional. Load with initial value and have
 | 
			
		||||
  // it shoot to new value immediately
 | 
			
		||||
  prevValue?: number;
 | 
			
		||||
  visible: boolean;
 | 
			
		||||
  fadeOnComplete: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface State {
 | 
			
		||||
  value: number;
 | 
			
		||||
  visible: boolean;
 | 
			
		||||
  startFade: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class SessionProgress extends React.PureComponent<Props, State> {
 | 
			
		||||
  public static defaultProps = {
 | 
			
		||||
    fadeOnComplete: true,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  constructor(props: any) {
 | 
			
		||||
    super(props);
 | 
			
		||||
 | 
			
		||||
    const { visible, value, prevValue } = this.props;
 | 
			
		||||
 | 
			
		||||
    this.state = {
 | 
			
		||||
      visible,
 | 
			
		||||
      startFade: false,
 | 
			
		||||
      value: prevValue || value,
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public componentWillMount() {
 | 
			
		||||
    setTimeout(() => {
 | 
			
		||||
      this.setState({
 | 
			
		||||
        value: this.props.value,
 | 
			
		||||
      });
 | 
			
		||||
    }, 20);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public render() {
 | 
			
		||||
    const { startFade, value } = this.state;
 | 
			
		||||
    const { prevValue } = this.props;
 | 
			
		||||
 | 
			
		||||
    // Duration will be the decimal (in seconds) of
 | 
			
		||||
    // the percentage differnce, else 0.25s;
 | 
			
		||||
    // Minimum shift duration of 0.25s;
 | 
			
		||||
    const shiftDuration = this.getShiftDuration(this.props.value, prevValue);
 | 
			
		||||
 | 
			
		||||
    // 1. Width depends on progress.
 | 
			
		||||
    // 2. Opacity is the inverse of fade.
 | 
			
		||||
    // 3. Transition duration scales with the 
 | 
			
		||||
    //    distance it needs to travel
 | 
			
		||||
    const style = {
 | 
			
		||||
      width: `${this.state.value}%`,
 | 
			
		||||
      opacity: `${Number(!startFade)}`,
 | 
			
		||||
      transition: `width ${shiftDuration.toFixed(2)}s cubic-bezier(0.25, 0.46, 0.45, 0.94)`,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    if (value >= 100) {
 | 
			
		||||
      this.onComplete();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <div className="session-progress">
 | 
			
		||||
            <div
 | 
			
		||||
                className="session-progress__progress"
 | 
			
		||||
                style={style}
 | 
			
		||||
            >
 | 
			
		||||
                 
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public onComplete() {
 | 
			
		||||
    const { fadeOnComplete } = this.props;
 | 
			
		||||
    
 | 
			
		||||
    // Fade
 | 
			
		||||
    if ( fadeOnComplete ) {
 | 
			
		||||
      this.setState({
 | 
			
		||||
        startFade: true,
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private getShiftDuration(value: number, prevValue?: number) {
 | 
			
		||||
    // Generates a shift duration which is based upon the distance requred to travel.
 | 
			
		||||
    // Follows the curve of y = (1-c)*sqrt(x) + c
 | 
			
		||||
    // Input values are between 0 and 100.
 | 
			
		||||
    // Max time = 1.0s.
 | 
			
		||||
 | 
			
		||||
    const minTime = 0.25;
 | 
			
		||||
    if (!prevValue) {
 | 
			
		||||
      return minTime;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const distance = Math.abs(value - prevValue) / 100;
 | 
			
		||||
    return (1 - minTime) * Math.sqrt(distance) + minTime;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
					Loading…
					
					
				
		Reference in New Issue