Working conversation openning

pull/1102/head
Vincent 5 years ago
parent 57b20d2f1a
commit bf5badda3b

@ -986,19 +986,7 @@
} }
return toastID; return toastID;
}; };
window.renderConversationView = conversationKey => {
const sessionConversation = new Whisper.SessionConversationView({
el: $('#main-view'),
conversationKey,
});
sessionConversation.render();
console.log(conversationKey);
console.log(conversationKey);
console.log(conversationKey);
};
window.getFriendsFromContacts = contacts => { window.getFriendsFromContacts = contacts => {
// To call from TypeScript, input / output are both // To call from TypeScript, input / output are both

@ -69,7 +69,9 @@
const conversation = window.getConversationByKey(key); const conversation = window.getConversationByKey(key);
// Grab messages and push to conv object. // Grab messages and push to conv object.
await conversation.fetchMessages(); if (!conversation.messageCollection.models.length){
await conversation.fetchMessages();
}
const messagesModel = conversation.messageCollection.models; const messagesModel = conversation.messageCollection.models;
const messages = messagesModel.map(conv => conv.attributes); const messages = messagesModel.map(conv => conv.attributes);
@ -77,7 +79,6 @@
return messages; return messages;
} }
window.ConversationController = { window.ConversationController = {
get(id) { get(id) {
if (!this._initialFetchComplete) { if (!this._initialFetchComplete) {

@ -146,6 +146,7 @@ const {
// State // State
const { createLeftPane } = require('../../ts/state/roots/createLeftPane'); const { createLeftPane } = require('../../ts/state/roots/createLeftPane');
const { createSessionConversation } = require('../../ts/state/roots/createSessionConversation');
const { createStore } = require('../../ts/state/createStore'); const { createStore } = require('../../ts/state/createStore');
const conversationsDuck = require('../../ts/state/ducks/conversations'); const conversationsDuck = require('../../ts/state/ducks/conversations');
const userDuck = require('../../ts/state/ducks/user'); const userDuck = require('../../ts/state/ducks/user');
@ -335,6 +336,7 @@ exports.setup = (options = {}) => {
const Roots = { const Roots = {
createLeftPane, createLeftPane,
createSessionConversation,
}; };
const Ducks = { const Ducks = {
conversations: conversationsDuck, conversations: conversationsDuck,

@ -21,61 +21,16 @@
Whisper.ConversationStack = Whisper.View.extend({ Whisper.ConversationStack = Whisper.View.extend({
className: 'conversation-stack', className: 'conversation-stack',
open(conversation) { open(conversation) {
const id = `conversation-${conversation.cid}`; // const container = $('#main-view .conversation-stack');
const container = $('#main-view .conversation-stack'); // container.html('');
// Has been opened since app start, but not focussed
const conversationExists = container.children(`#${id}`).length > 0;
// Is focussed
const conversationOpened = container.children().first().id === id;
// To limit the size of the DOM for speed
const maxNumConversations = 10;
const numConversations = container
.children()
.not('.conversation.placeholder').length;
const shouldTrimConversations = numConversations > maxNumConversations;
if (shouldTrimConversations) {
// Removes conversation which has been hidden the longest
container.children()[numConversations - 1].remove();
}
if (conversationExists) {
// User opened conversation, move it to top of stack, rather than re-rendering
const conversations = container
.children()
.not('.conversation.placeholder');
container
.children(`#${id}`)
.first()
.insertBefore(conversations.first());
conversation.trigger('opened');
return;
}
if (!conversationOpened) { this.setupSessionConversation();
this.$el // const sessionConversationView = new Whisper.SessionConversationView({
.first() // el: container,
.find('video, audio') // conversationKey: conversation.id,
.each(function pauseMedia() { // });
this.pause(); // sessionConversationView.render();
});
let $el = this.$(`#${id}`);
if ($el === null || $el.length === 0) {
const view = new Whisper.ConversationView({
model: conversation,
window: this.model.window,
});
view.view.resetScrollPosition();
// eslint-disable-next-line prefer-destructuring
$el = view.$el;
}
container.prepend($el);
}
conversation.trigger('opened'); conversation.trigger('opened');
}, },
close(conversation) { close(conversation) {
@ -98,6 +53,77 @@
reject: onCancel, reject: onCancel,
}); });
}, },
setupSessionConversation() {
// Here we set up a full redux store with initial state for our LeftPane Root
const convoCollection = getConversations();
const conversations = convoCollection.map(
conversation => conversation.cachedProps
);
const initialState = {
conversations: {
conversationLookup: Signal.Util.makeLookup(conversations, 'id'),
},
user: {
regionCode: window.storage.get('regionCode'),
ourNumber:
window.storage.get('primaryDevicePubKey') ||
textsecure.storage.user.getNumber(),
isSecondaryDevice: !!window.storage.get('isSecondaryDevice'),
i18n: window.i18n,
},
};
this.store = Signal.State.createStore(initialState);
window.inboxStore = this.store;
this.sessionConversationView = new Whisper.ReactWrapperView({
JSX: Signal.State.Roots.createSessionConversation(this.store),
className: 'session-conversation-redux-wrapper',
});
// Enables our redux store to be updated by backbone events in the outside world
const {
conversationAdded,
conversationChanged,
conversationRemoved,
removeAllConversations,
messageExpired,
openConversationExternal,
} = Signal.State.bindActionCreators(
Signal.State.Ducks.conversations.actions,
this.store.dispatch
);
const { userChanged } = Signal.State.bindActionCreators(
Signal.State.Ducks.user.actions,
this.store.dispatch
);
this.openConversationAction = openConversationExternal;
this.listenTo(convoCollection, 'remove', conversation => {
const { id } = conversation || {};
conversationRemoved(id);
});
this.listenTo(convoCollection, 'add', conversation => {
const { id, cachedProps } = conversation || {};
conversationAdded(id, cachedProps);
});
this.listenTo(convoCollection, 'change', conversation => {
const { id, cachedProps } = conversation || {};
conversationChanged(id, cachedProps);
});
this.listenTo(convoCollection, 'reset', removeAllConversations);
Whisper.events.on('messageExpired', messageExpired);
Whisper.events.on('userChanged', userChanged);
// Add sessionConversation to the DOM
// Don't worry - this isn't fetching messages on every re-render. It's pulling
// from Redux
// $('#main-view .conversation-stack').html('');
$('#main-view .conversation-stack').prepend(this.sessionConversationView.el);
},
}); });
Whisper.AppLoadingScreen = Whisper.View.extend({ Whisper.AppLoadingScreen = Whisper.View.extend({
@ -345,7 +371,7 @@
} }
this.conversation_stack.open(conversation); this.conversation_stack.open(conversation);
this.focusConversation(); // this.focusConversation();
}, },
closeConversation(conversation) { closeConversation(conversation) {
if (conversation) { if (conversation) {

@ -109,7 +109,7 @@ export class LeftPaneMessageSection extends React.Component<Props, any> {
key, key,
style, style,
}: RowRendererParamsType): JSX.Element => { }: RowRendererParamsType): JSX.Element => {
// const { openConversationInternal } = this.props; const { openConversationInternal } = this.props;
const conversations = this.getCurrentConversations(); const conversations = this.getCurrentConversations();
@ -125,7 +125,7 @@ export class LeftPaneMessageSection extends React.Component<Props, any> {
key={key} key={key}
style={style} style={style}
{...conversation} {...conversation}
onClick={() => window.renderConversationView(conversationKey)} onClick={openConversationInternal}
i18n={window.i18n} i18n={window.i18n}
/> />
); );

@ -8,181 +8,191 @@ import { Message } from '../conversation/Message';
import { SessionSpinner } from './SessionSpinner'; import { SessionSpinner } from './SessionSpinner';
interface Props { // interface Props {
getHeaderProps: any; // getHeaderProps: any;
conversationKey: any; // conversationKey: any;
} // }
interface State { // interface State {
sendingProgess: number; // sendingProgess: number;
prevSendingProgess: number; // prevSendingProgess: number;
messages: Array<any>; // messages: Array<any>;
} // }
export class SessionConversation extends React.Component<Props, State> { export class SessionConversation extends React.Component<any, any> {
constructor(props: any) { constructor(props: any) {
super(props); super(props);
this.state = { // this.state = {
sendingProgess: 0, // sendingProgess: 0,
prevSendingProgess: 0, // prevSendingProgess: 0,
messages: [], // messages: [],
}; // };
} }
async componentWillMount() { // async componentWillMount() {
const { conversationKey } = this.props; // const { conversationKey } = this.props;
this.setState({ // this.setState({
messages: await window.getMessagesByKey(conversationKey) // messages: await window.getMessagesByKey(conversationKey)
}); // });
} // }
render() { render() {
// const headerProps = this.props.getHeaderProps; // console.log(`[vince]`, this.props);
const { conversationKey } = this.props;
const loadingMessages = this.state.messages.length === 0; // // const headerProps = this.props.getHeaderProps;
// const { conversationKey } = this.props;
// TMEPORARY SOLUTION TO GETTING CONVERSATION UNTIL // const loadingMessages = this.state.messages.length === 0;
// SessionConversationStack is created
// // TMEPORARY SOLUTION TO GETTING CONVERSATION UNTIL
// Get conversation by Key (NOT cid) // // SessionConversationStack is created
const conversation = window.getConversationByKey(conversationKey);
const conversationType = conversation.attributes.type; // // Get conversation by Key (NOT cid)
// const conversation = window.getConversationByKey(conversationKey);
console.log(`Conversation key: `, conversationKey); // const conversationType = conversation.attributes.type;
return ( // console.log(`Conversation key: `, conversationKey);
<div className={`conversation-item conversation-${conversation.cid}`}>
<div className="conversation-header"> // return (
{this.renderHeader(conversation)} // <div className={`conversation-item conversation-${conversation.cid}`}>
</div> // <div className="conversation-header">
// {this.renderHeader(conversation)}
<SessionProgress // </div>
visible={true}
value={this.state.sendingProgess} // <SessionProgress
prevValue={this.state.prevSendingProgess} // visible={true}
/> // value={this.state.sendingProgess}
// prevValue={this.state.prevSendingProgess}
// />
// <div className="messages-container">
// { loadingMessages ? (
// <div className="messages-container__loading">
// <SessionSpinner/>
// </div>
// ) : (
// <>
// {/*this.renderMessages(conversationKey, conversationType)*/}
// {this.props.conversations[0].lastMessage}
// </>
// )}
// </div>
// <SessionCompositionBox
<div className="messages-container"> // onSendMessage={() => null}
{ loadingMessages ? ( // />
<div className="messages-container__loading"> // </div>
<SessionSpinner/> // );
</div>
) : (
<>
{this.renderMessages(conversationKey, conversationType)}
</>
)}
</div>
<SessionCompositionBox
onSendMessage={() => null}
/>
</div>
);
}
public renderMessages(conversationKey: string, conversationType: 'group' | 'direct') {
const { messages } = this.state;
console.log(`Messages`, messages);
// FIND FOR EACH MESSAGE
const isExpired = false;
const isDeletable = false;
const messageType = 'direct';
const selected = false;
const preview:any = [];
const multiSelectMode = false;
const onSelectMessage = () => null;
const onSelectMessageUnchecked = () => null;
const onShowDetail = () => null;
const onShowUserDetails = () => null;
// FIXME PAY ATTENTION; ONLY RENDER MESSAGES THAT ARE VISIBLE
return (
<>{
messages.map((message: any) => (
<Message
text = {message.body || ''}
direction = {'incoming'}
timestamp = {1581565995228}
i18n = {window.i18n}
authorPhoneNumber = {message.source}
conversationType = {conversationType}
previews = {preview}
isExpired = {isExpired}
isDeletable = {isDeletable}
convoId = {conversationKey}
selected = {selected}
multiSelectMode = {multiSelectMode}
onSelectMessage = {onSelectMessage}
onSelectMessageUnchecked = {onSelectMessageUnchecked}
onShowDetail = {onShowDetail}
onShowUserDetails = {onShowUserDetails}
/>
))
}</>
);
}
public renderHeader(conversation: any) {
return ( return (
<ConversationHeader <>
id={conversation.cid} {/*this.props.conversations[0].lastMessage*/}
phoneNumber={conversation.id} Lorem ipsum dolor sit amet consectetur, adipisicing elit. Quidem fugiat omnis aperiam nulla ducimus dolores, molestias hic aliquam laboriosam velit, quas quis autem distinctio vero beatae id tempora error nostrum?
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}
/>
);
}
public scrollToUnread() {
} }
public scrollToBottom() { // public renderMessages(conversationKey: string, conversationType: 'group' | 'direct') {
// const { messages } = this.state;
}
} // console.log(`Messages`, messages);
// // FIND FOR EACH MESSAGE
// const isExpired = false;
// const isDeletable = false;
// const messageType = 'direct';
// const selected = false;
// const preview:any = [];
// const multiSelectMode = false;
// const onSelectMessage = () => null;
// const onSelectMessageUnchecked = () => null;
// const onShowDetail = () => null;
// const onShowUserDetails = () => null;
// // FIXME PAY ATTENTION; ONLY RENDER MESSAGES THAT ARE VISIBLE
// return (
// <>{
// messages.map((message: any) => {
// return message.body && (
// <Message
// text = {message.body || ''}
// direction = {'incoming'}
// timestamp = {1581565995228}
// i18n = {window.i18n}
// authorPhoneNumber = {message.source}
// conversationType = {conversationType}
// previews = {preview}
// isExpired = {isExpired}
// isDeletable = {isDeletable}
// convoId = {conversationKey}
// selected = {selected}
// multiSelectMode = {multiSelectMode}
// onSelectMessage = {onSelectMessage}
// onSelectMessageUnchecked = {onSelectMessageUnchecked}
// onShowDetail = {onShowDetail}
// onShowUserDetails = {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}
// />
// );
// }
// public scrollToUnread() {
// }
// public scrollToBottom() {
// }
// }

@ -0,0 +1,16 @@
import React from 'react';
import { Provider } from 'react-redux';
import { Store } from 'redux';
import { SmartSessionConversation } from '../smart/SessionConversation';
// Workaround: A react component's required properties are filtering up through connect()
// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/31363
const FilteredSessionConversation = SmartSessionConversation as any;
export const createSessionConversation = (store: Store) => (
<Provider store={store as any}>
<FilteredSessionConversation />
</Provider>
);

@ -0,0 +1,15 @@
import { connect } from 'react-redux';
import { mapDispatchToProps } from '../actions';
import { SessionConversation } from '../../components/session/SessionConversation';
import { StateType } from '../reducer';
import { getLeftPaneLists } from '../selectors/conversations';
const mapStateToProps = (state: StateType) => {
const lists = getLeftPaneLists(state);
return lists;
};
const smart = connect(mapStateToProps, mapDispatchToProps);
export const SmartSessionConversation = smart(SessionConversation);
Loading…
Cancel
Save