Message loading with redux

pull/1102/head
Vincent 5 years ago
parent 3fec09a293
commit 1689bc617e

@ -65,20 +65,39 @@
return conversation;
}
window.getMessagesByKey = async key => {
const conversation = window.getConversationByKey(key);
// Grab messages and push to conv object.
if (!conversation.messageCollection.models.length){
await conversation.fetchMessages();
}
const messagesModel = conversation.messageCollection.models;
const messages = messagesModel.map(conv => conv.attributes);
window.getMessagesByKey = async (key, loadLive = false) => {
// loadLive gets messages live, not from the database which can lag behind.
let messages = [];
let messageSet;
// if (loadLive){
messageSet = await window.Signal.Data.getMessagesByConversation(
key,
{ limit: 100, MessageCollection: Whisper.MessageCollection }
);
// } else {
// const conversation = window.getConversationByKey(key);
// // Grab messages and push to conv object.
// await conversation.fetchMessages();
// messageSet = conversation.messageCollection;
// }
messages = messageSet.models.map(conv => conv.attributes);
return messages;
}
window.getLastMessageByKey = async key => {
const messageSet = await window.Signal.Data.getMessagesByConversation(
key,
{ limit: 1, MessageCollection: Whisper.MessageCollection }
);
const message = messageSet.models.map(conv => conv.attributes)[0];
return message;
}
window.ConversationController = {
get(id) {
if (!this._initialFetchComplete) {

@ -770,6 +770,9 @@ async function updateConversation(id, data, { Conversation }) {
throw new Error(`Conversation ${id} does not exist!`);
}
console.log(`[vince][update] Updating conversation ${id}`);
console.log(`[vince][update] New data:`, data);
const merged = _.merge({}, existing.attributes, data);
// Merging is a really bad idea and not what we want here, e.g.

@ -53,74 +53,15 @@
reject: onCancel,
});
},
setupSessionConversation(conversationId) {
setupSessionConversation() {
// Here we set up a full redux store with initial state for our Conversation 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,
},
};
const store = Signal.State.createStore(initialState);
window.conversationStore = store;
this.sessionConversationView = new Whisper.ReactWrapperView({
JSX: Signal.State.Roots.createSessionConversation(store),
JSX: Signal.State.Roots.createSessionConversation(window.inboxStore),
className: 'conversation-item',
});
// 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,
store.dispatch
);
const { userChanged } = Signal.State.bindActionCreators(
Signal.State.Ducks.user.actions,
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').append(this.sessionConversationView.el);
},

@ -28,23 +28,23 @@ interface State {
}
interface Props {
// conversations: Array<ConversationListItemPropsType>;
// friends: Array<ConversationType>;
// sentFriendsRequest: Array<ConversationListItemPropsType>;
// receivedFriendsRequest: Array<ConversationListItemPropsType>;
// unreadMessageCount: number;
// receivedFriendRequestCount: number;
// searchResults?: SearchResultsProps;
// searchTerm: string;
// isSecondaryDevice: boolean;
// openConversationInternal: (id: string, messageId?: string) => void;
// updateSearchTerm: (searchTerm: string) => void;
// search: (query: string, options: SearchOptions) => void;
// clearSearch: () => void;
conversations: Array<ConversationListItemPropsType>;
friends: Array<ConversationType>;
sentFriendsRequest: Array<ConversationListItemPropsType>;
receivedFriendsRequest: Array<ConversationListItemPropsType>;
unreadMessageCount: number;
receivedFriendRequestCount: number;
searchResults?: SearchResultsProps;
searchTerm: string;
isSecondaryDevice: boolean;
openConversationInternal: (id: string, messageId?: string) => void;
updateSearchTerm: (searchTerm: string) => void;
search: (query: string, options: SearchOptions) => void;
clearSearch: () => void;
}
export class LeftPane extends React.Component<any, State> {
export class LeftPane extends React.Component<Props, State> {
public state = {
selectedSection: SectionType.Message,
};
@ -52,9 +52,6 @@ export class LeftPane extends React.Component<any, State> {
public constructor(props: any) {
super(props);
this.handleSectionSelected = this.handleSectionSelected.bind(this);
console.log(`[vince] These are my props:`, props);
}
// this static function is set here to be used by all subsections (message, contacts,...) to render their headers
@ -83,6 +80,7 @@ export class LeftPane extends React.Component<any, State> {
}
public render(): JSX.Element {
return (
<div className="module-left-pane-session">
<ActionsPanel

@ -6,6 +6,7 @@ import { SessionProgress } from './SessionProgress'
import { Message } from '../conversation/Message';
import { SessionSpinner } from './SessionSpinner';
import { configure } from 'protobufjs';
// interface Props {
@ -23,7 +24,7 @@ interface State {
export class SessionConversation extends React.Component<any, State> {
constructor(props: any) {
super(props);
const conversationKey = window.inboxStore.getState().conversations.selectedConversation;
const conversationKey = this.props.conversations.selectedConversation;
this.state = {
sendingProgess: 0,
@ -31,33 +32,51 @@ export class SessionConversation extends React.Component<any, State> {
conversationKey,
messages: [],
};
}
public async componentWillUpdate () {
console.log(`[vince][update] State:`, this.state);
console.log(`[vince][update] Props:`, this.props);
}
async componentWillMount() {
const {conversationKey} = this.state;
public async componentWillReceiveProps() {
const { conversationKey, messages } = this.state;
const conversation = this.props.conversations.conversationLookup[conversationKey];
// Check if another message came through
const shouldLoad = !messages.length || (conversation.lastUpdated > messages[messages.length - 1]?.received_at);
console.log(`[vince][update] conversation:`, conversation);
console.log(`[vince][update] conversation.lastupdated: `, conversation.lastUpdated)
console.log(`[vince][update] last message received at: `, messages[messages.length - 1]?.received_at)
console.log(`[vince][update] Should Update: `, shouldLoad)
console.log(`[vince][update] called ComponentWillRevieceProps. Messages: `, this.state.messages)
if (conversationKey){
if (conversationKey && shouldLoad){
this.setState({
messages: await window.getMessagesByKey(conversationKey)
messages: await window.getMessagesByKey(conversationKey, true)
});
}
}
render() {
console.log('[vince] SessionConversation was just rerendered!');
console.log(`[vince] These are SessionConversation props: `, this.props);
// const headerProps = this.props.getHeaderProps;
const { conversationKey } = this.state;
const loadingMessages = this.state.messages.length === 0;
console.log(`[vince] My conversation key is: `, conversationKey);
// TMEPORARY SOLUTION TO GETTING CONVERSATION UNTIL
// SessionConversationStack is created
// Get conversation by Key (NOT cid)
const conversation = window.getConversationByKey(conversationKey);
const conversationType = conversation.attributes.type;
console.log(`[vince] Conversation key: `, conversationKey);
console.log(`[vince] Conversation:`, conversation);
const conversation = this.props.conversations.conversationLookup[conversationKey]
const conversationType = conversation.type;
return (
<div className={`conversation-item conversation-${conversation.cid}`}>

1
ts/global.d.ts vendored

@ -14,6 +14,7 @@ interface Window {
getConversations: any;
getConversationByKey: any;
getMessagesByKey: any;
getLastMessageByKey: any;
getFriendsFromContacts: any;
mnemonic: any;

@ -62,6 +62,7 @@ export type ConversationLookupType = {
export type ConversationsStateType = {
conversationLookup: ConversationLookupType;
messageCollection: string;
selectedConversation?: string;
showArchived: boolean;
};
@ -238,6 +239,7 @@ function showArchivedConversations() {
function getEmptyState(): ConversationsStateType {
return {
conversationLookup: {},
messageCollection: 'stuff',
showArchived: false,
};
}
@ -247,7 +249,7 @@ export function reducer(
action: ConversationActionType
): ConversationsStateType {
if (!state) {
return getEmptyState();\
return getEmptyState();
}
if (action.type === 'CONVERSATION_ADDED') {
@ -291,10 +293,17 @@ export function reducer(
}
}
let lastMessage: any;
window.getLastMessageByKey(id).then((message: any) => lastMessage = message);
const messages = [...state.messageCollection].push(lastMessage);
console.log(`[vince][update] Updated messages to `, messages);
return {
...state,
selectedConversation,
showArchived,
messageCollection: 'afgjvhbrgvkhbrg',
conversationLookup: {
...conversationLookup,
[id]: data,

@ -9,10 +9,13 @@ const mapStateToProps = (state: StateType) => {
//const conversationInfo = getSessionConversationInfo(state);
// console.log(`[vince] stateToProps from SessionConversation:`, conversationInfo);
console.log(`[vince] stateToProps from SessionConversation:`,state);
// console.log(`[vince] stateToProps from SessionConversation:`, state);
// You only want to rerender SessionConversation if the CURRENT conversation updates
// Use SelectedConversationChangedActionType FROM actions.ts
return {
...state,
conversations: state.conversations,
}
};

Loading…
Cancel
Save