Working conversation openning

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

@ -988,18 +988,6 @@
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
// of type Array<ConversationType> // of type Array<ConversationType>

@ -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.
if (!conversation.messageCollection.models.length){
await conversation.fetchMessages(); 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.$el
.first()
.find('video, audio')
.each(function pauseMedia() {
this.pause();
});
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 this.setupSessionConversation();
$el = view.$el; // const sessionConversationView = new Whisper.SessionConversationView({
} // el: container,
// conversationKey: conversation.id,
// });
// sessionConversationView.render();
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;
// 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">
// { loadingMessages ? (
// <div className="messages-container__loading">
// <SessionSpinner/>
// </div>
// ) : (
// <>
// {/*this.renderMessages(conversationKey, conversationType)*/}
// {this.props.conversations[0].lastMessage}
// </>
// )}
// </div>
// <SessionCompositionBox
// onSendMessage={() => null}
// />
// </div>
// );
return ( 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">
{ loadingMessages ? (
<div className="messages-container__loading">
<SessionSpinner/>
</div>
) : (
<> <>
{this.renderMessages(conversationKey, conversationType)} {/*this.props.conversations[0].lastMessage*/}
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?
</> </>
)} )
</div>
<SessionCompositionBox
onSendMessage={() => null}
/>
</div>
);
} }
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(`Messages`, messages);
// FIND FOR EACH MESSAGE // // FIND FOR EACH MESSAGE
const isExpired = false; // const isExpired = false;
const isDeletable = false; // const isDeletable = false;
const messageType = 'direct'; // const messageType = 'direct';
const selected = false; // const selected = false;
const preview:any = []; // const preview:any = [];
const multiSelectMode = false; // const multiSelectMode = false;
const onSelectMessage = () => null; // const onSelectMessage = () => null;
const onSelectMessageUnchecked = () => null; // const onSelectMessageUnchecked = () => null;
const onShowDetail = () => null; // const onShowDetail = () => null;
const onShowUserDetails = () => null; // const onShowUserDetails = () => null;
// FIXME PAY ATTENTION; ONLY RENDER MESSAGES THAT ARE VISIBLE // // FIXME PAY ATTENTION; ONLY RENDER MESSAGES THAT ARE VISIBLE
return ( // return (
<>{ // <>{
messages.map((message: any) => ( // messages.map((message: any) => {
<Message
text = {message.body || ''} // return message.body && (
direction = {'incoming'} // <Message
timestamp = {1581565995228} // text = {message.body || ''}
i18n = {window.i18n} // direction = {'incoming'}
authorPhoneNumber = {message.source} // timestamp = {1581565995228}
conversationType = {conversationType} // i18n = {window.i18n}
previews = {preview} // authorPhoneNumber = {message.source}
isExpired = {isExpired} // conversationType = {conversationType}
isDeletable = {isDeletable} // previews = {preview}
convoId = {conversationKey} // isExpired = {isExpired}
selected = {selected} // isDeletable = {isDeletable}
multiSelectMode = {multiSelectMode} // convoId = {conversationKey}
onSelectMessage = {onSelectMessage} // selected = {selected}
onSelectMessageUnchecked = {onSelectMessageUnchecked} // multiSelectMode = {multiSelectMode}
onShowDetail = {onShowDetail} // onSelectMessage = {onSelectMessage}
onShowUserDetails = {onShowUserDetails} // onSelectMessageUnchecked = {onSelectMessageUnchecked}
/> // onShowDetail = {onShowDetail}
)) // onShowUserDetails = {onShowUserDetails}
}</> // />
); // )}
// )
} // }</>
// );
public renderHeader(conversation: any) {
return ( // }
<ConversationHeader
id={conversation.cid} // public renderHeader(conversation: any) {
phoneNumber={conversation.id} // return (
isVerified={true} // <ConversationHeader
isMe={false} // id={conversation.cid}
isFriend={true} // phoneNumber={conversation.id}
i18n={window.i18n} // isVerified={true}
isGroup={false} // isMe={false}
isArchived={false} // isFriend={true}
isPublic={false} // i18n={window.i18n}
isRss={false} // isGroup={false}
amMod={false} // isArchived={false}
members={[]} // isPublic={false}
showBackButton={false} // isRss={false}
timerOptions={[]} // amMod={false}
isBlocked={false} // members={[]}
hasNickname={false} // showBackButton={false}
isFriendRequestPending={false} // timerOptions={[]}
isOnline={true} // isBlocked={false}
selectedMessages={null} // hasNickname={false}
onSetDisappearingMessages={() => null} // isFriendRequestPending={false}
onDeleteMessages={() => null} // isOnline={true}
onDeleteContact={() => null} // selectedMessages={null}
onResetSession={() => null} // onSetDisappearingMessages={() => null}
onCloseOverlay={() => null} // onDeleteMessages={() => null}
onDeleteSelectedMessages={() => null} // onDeleteContact={() => null}
onArchive={() => null} // onResetSession={() => null}
onMoveToInbox={() => null} // onCloseOverlay={() => null}
onShowSafetyNumber={() => null} // onDeleteSelectedMessages={() => null}
onShowAllMedia={() => null} // onArchive={() => null}
onShowGroupMembers={() => null} // onMoveToInbox={() => null}
onGoBack={() => null} // onShowSafetyNumber={() => null}
onBlockUser={() => null} // onShowAllMedia={() => null}
onUnblockUser={() => null} // onShowGroupMembers={() => null}
onClearNickname={() => null} // onGoBack={() => null}
onChangeNickname={() => null} // onBlockUser={() => null}
onCopyPublicKey={() => null} // onUnblockUser={() => null}
onLeaveGroup={() => null} // onClearNickname={() => null}
onAddModerators={() => null} // onChangeNickname={() => null}
onRemoveModerators={() => null} // onCopyPublicKey={() => null}
onInviteFriends={() => null} // onLeaveGroup={() => null}
/> // onAddModerators={() => null}
); // onRemoveModerators={() => null}
} // onInviteFriends={() => null}
// />
public scrollToUnread() { // );
// }
}
// public scrollToUnread() {
public scrollToBottom() {
// }
}
} // 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