Message conditional rendering

pull/1102/head
Vincent 5 years ago
parent d662fcfa1a
commit 752ee8a614

@ -1,3 +1,5 @@
export function searchMessages(query: string): Promise<Array<any>>; export function searchMessages(query: string): Promise<Array<any>>;
export function searchConversations(query: string): Promise<Array<any>>; export function searchConversations(query: string): Promise<Array<any>>;
export function getPrimaryDeviceFor(pubKey: string): Promise<string | null>; export function getPrimaryDeviceFor(pubKey: string): Promise<string | null>;
export function getMessagesByConversation(conversationId: string, destructurer: any): Promise<Array<any>>;

@ -770,9 +770,6 @@ async function updateConversation(id, data, { Conversation }) {
throw new Error(`Conversation ${id} does not exist!`); 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); const merged = _.merge({}, existing.attributes, data);
// Merging is a really bad idea and not what we want here, e.g. // Merging is a really bad idea and not what we want here, e.g.

@ -70,6 +70,9 @@ window.CONSTANTS = {
MAX_MESSAGE_BODY_LENGTH: 64 * 1024, MAX_MESSAGE_BODY_LENGTH: 64 * 1024,
// Limited due to the proof-of-work requirement // Limited due to the proof-of-work requirement
SMALL_GROUP_SIZE_LIMIT: 10, SMALL_GROUP_SIZE_LIMIT: 10,
DEFAULT_MEDIA_FETCH_COUNT: 50,
DEFAULT_DOCUMENTS_FETCH_COUNT: 150,
DEFAULT_MESSAGE_FETCH_COUNT: 30,
}; };
window.versionInfo = { window.versionInfo = {

@ -28,7 +28,6 @@ $composition-container-height: 60px;
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; position: absolute;

@ -5,16 +5,17 @@ import { SessionCompositionBox } from './SessionCompositionBox';
import { SessionProgress } from './SessionProgress' import { SessionProgress } from './SessionProgress'
import { Message } from '../conversation/Message'; import { Message } from '../conversation/Message';
import { TimerNotification } from '../conversation/TimerNotification';
import { SessionSpinner } from './SessionSpinner'; import { SessionSpinner } from './SessionSpinner';
import { SessionScrollButton } from './SessionScrollButton'; import { SessionScrollButton } from './SessionScrollButton';
// interface Props { // interface Props {
// getHeaderProps: any; // getHeaderProps: any;
// conversationKey: any; // conversationKey: any;
// } // }
interface State { interface State {
sendingProgess: number; sendingProgess: number;
prevSendingProgess: number; prevSendingProgess: number;
@ -33,13 +34,12 @@ export class SessionConversation extends React.Component<any, State> {
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, doneInitialScroll: false,
scrollPositionPc: 0, scrollPositionPc: 0,
scrollPositionPx: 0, scrollPositionPx: 0,
@ -48,47 +48,29 @@ export class SessionConversation extends React.Component<any, State> {
this.scrollToUnread = this.scrollToUnread.bind(this); this.scrollToUnread = this.scrollToUnread.bind(this);
this.scrollToBottom = this.scrollToBottom.bind(this); this.scrollToBottom = this.scrollToBottom.bind(this);
this.renderMessage = this.renderMessage.bind(this);
this.renderTimerNotification = this.renderTimerNotification.bind(this);
this.messagesEndRef = React.createRef(); this.messagesEndRef = React.createRef();
} }
public componentDidMount() { public async componentWillMount() {
const { conversationKey } = this.state;
await this.getMessages(conversationKey);
setTimeout(() => { setTimeout(() => {
this.scrollToBottom(true); this.scrollToBottom(true);
}, 20); }, 0);
setTimeout(() => {
this.setState({ this.setState({
doneInitialScroll: true, doneInitialScroll: true,
}); });
} }, 100);
public componentWillUpdate () {
console.log(`[vince][update] State:`, this.state);
console.log(`[vince][update] Props:`, this.props);
} }
public componentWillReceiveProps() { public async componentWillReceiveProps() {
const { conversationKey, messages } = this.state; const { conversationKey } = 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 && shouldLoad){
// this.setState({
// messages: await window.getMessagesByKey(conversationKey, true)
// });
// }
// this.setState({
// messages: this.props.conversations.conversationLookup[conversationKey]?.messsages,
// });
} }
@ -98,17 +80,18 @@ export class SessionConversation extends React.Component<any, State> {
// const headerProps = this.props.getHeaderProps; // const headerProps = this.props.getHeaderProps;
const { messages, conversationKey, doneInitialScroll } = this.state; const { messages, conversationKey, doneInitialScroll } = this.state;
const loading = !doneInitialScroll const loading = !doneInitialScroll || messages.length === 0;
console.log(`[vince] Loading: `, loading); console.log(`[vince] Loading: `, loading);
console.log(`[vince] My conversation key is: `, conversationKey); console.log(`[vince] My conversation key is: `, conversationKey);
console.log(`[vince][messages]`, messages);
// TMEPORARY SOLUTION TO GETTING CONVERSATION UNTIL // TMEPORARY SOLUTION TO GETTING CONVERSATION UNTIL
// SessionConversationStack is created // SessionConversationStack is created
// Get conversation by Key (NOT cid) // Get conversation by Key (NOT cid)
const conversation = this.props.conversations.conversationLookup[conversationKey] const conversation = this.props.conversations.conversationLookup[conversationKey]
const conversationType = conversation.type;
return ( return (
<div className="conversation-item"> <div className="conversation-item">
@ -125,12 +108,12 @@ export class SessionConversation extends React.Component<any, State> {
<div className="messages-wrapper"> <div className="messages-wrapper">
{ loading && ( { loading && (
<div className="messages-container__loading"> <div className="messages-container__loading">
<SessionSpinner/> {/* <SessionSpinner/> */}
</div> </div>
)} )}
<div className="messages-container"> <div className="messages-container">
{this.renderMessages(conversationKey, conversationType)} {this.renderMessages(conversationKey)}
<div ref={this.messagesEndRef} /> <div ref={this.messagesEndRef} />
</div> </div>
@ -146,50 +129,31 @@ export class SessionConversation extends React.Component<any, State> {
); );
} }
public renderMessages(conversationKey: string, conversationType: 'group' | 'direct') { public renderMessages() {
const { messages } = this.state; const { messages } = this.state;
console.log(`[vince][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 // FIXME PAY ATTENTION; ONLY RENDER MESSAGES THAT ARE VISIBLE
return ( return (
<>{ <>{
messages.map((message: any) => { messages.map((message: any) => {
const messageProps = message.propsForMessage;
return message.body && ( const timerProps = message.propsForTimerNotification;
<Message const attachmentProps = message.propsForAttachment;
text = {message.body || ''} const quoteProps = message.propsForQuote;
direction = {'incoming'}
timestamp = {1581565995228} console.log(`[vince][props] messageProps`, messageProps);
i18n = {window.i18n} console.log(`[vince][props] timerProps`, timerProps);
authorPhoneNumber = {message.source} console.log(`[vince][props] attachmentProps`, attachmentProps);
conversationType = {conversationType} console.log(`[vince][props] quoteProps`, quoteProps);
previews = {preview}
isExpired = {isExpired} let item;
isDeletable = {isDeletable} item = messageProps ? this.renderMessage(messageProps) : item;
convoId = {conversationKey} item = timerProps ? this.renderTimerNotification(timerProps) : item;
selected = {selected} item = attachmentProps ? this.renderMessage(timerProps) : item;
multiSelectMode = {multiSelectMode} item = quoteProps ? this.renderMessage(timerProps) : item;
onSelectMessage = {onSelectMessage}
onSelectMessageUnchecked = {onSelectMessageUnchecked} return item;
onShowDetail = {onShowDetail} })
onShowUserDetails = {onShowUserDetails}
/>
)}
)
}</> }</>
); );
@ -251,4 +215,54 @@ export class SessionConversation extends React.Component<any, State> {
{ behavior: firstLoad ? 'auto' : 'smooth' } { behavior: firstLoad ? 'auto' : 'smooth' }
); );
} }
public async getMessages(conversationKey: string, limit = window.CONSTANTS.DEFAULT_MESSAGE_FETCH_COUNT){
const messageSet = await window.Signal.Data.getMessagesByConversation(
conversationKey,
{ limit, MessageCollection: window.Whisper.MessageCollection },
);
console.log(`[vince][messages] MessageSet!!!`, messageSet);32
const messages = messageSet.models;
this.setState({ messages });
} }
public renderMessage(messageProps: any) {
return (
<Message
text = {messageProps.text || ''}
direction = {messageProps.direction}
timestamp = {messageProps.timestamp}
i18n = {window.i18n}
authorPhoneNumber = {messageProps.source}
conversationType = {messageProps.conversationType}
previews = {messageProps.previews}
isExpired = {messageProps.isExpired}
isDeletable = {messageProps.isDeletable}
convoId = {messageProps.convoId}
selected = {messageProps.selected}
multiSelectMode = {messageProps.multiSelectMode}
onSelectMessage = {messageProps.onSelectMessage}
onSelectMessageUnchecked = {messageProps.onSelectMessageUnchecked}
onShowDetail = {messageProps.onShowDetail}
onShowUserDetails = {messageProps.onShowUserDetails}
/>
);
}
public renderTimerNotification(timerProps: any) {
return (
<TimerNotification
type={timerProps.type}
phoneNumber={timerProps.phoneNumber}
profileName={timerProps.profileName}
name={timerProps.name}
disabled={timerProps.disabled}
timespan={timerProps.timespan}
i18n={window.i18n}
/>
);
}
}

@ -72,20 +72,18 @@ export class SessionGroupSettings extends React.Component<Props, any> {
public async getMediaGalleryProps() { public async getMediaGalleryProps() {
// We fetch more documents than media as they dont require to be loaded // We fetch more documents than media as they dont require to be loaded
// into memory right away. Revisit this once we have infinite scrolling: // into memory right away. Revisit this once we have infinite scrolling:
const DEFAULT_MEDIA_FETCH_COUNT = 50;
const DEFAULT_DOCUMENTS_FETCH_COUNT = 150;
const conversationId = this.props.id; const conversationId = this.props.id;
const rawMedia = await window.Signal.Data.getMessagesWithVisualMediaAttachments( const rawMedia = await window.Signal.Data.getMessagesWithVisualMediaAttachments(
conversationId, conversationId,
{ {
limit: DEFAULT_MEDIA_FETCH_COUNT, limit: window.CONSTANTS.DEFAULT_MEDIA_FETCH_COUNT,
MessageCollection: window.Whisper.MessageCollection, MessageCollection: window.Whisper.MessageCollection,
} }
); );
const rawDocuments = await window.Signal.Data.getMessagesWithFileAttachments( const rawDocuments = await window.Signal.Data.getMessagesWithFileAttachments(
conversationId, conversationId,
{ {
limit: DEFAULT_DOCUMENTS_FETCH_COUNT, limit: window.CONSTANTS.DEFAULT_DOCUMENTS_FETCH_COUNT,
MessageCollection: window.Whisper.MessageCollection, MessageCollection: window.Whisper.MessageCollection,
} }
); );

@ -62,7 +62,6 @@ export type ConversationLookupType = {
export type ConversationsStateType = { export type ConversationsStateType = {
conversationLookup: ConversationLookupType; conversationLookup: ConversationLookupType;
messageCollection: string;
selectedConversation?: string; selectedConversation?: string;
showArchived: boolean; showArchived: boolean;
}; };
@ -239,7 +238,6 @@ function showArchivedConversations() {
function getEmptyState(): ConversationsStateType { function getEmptyState(): ConversationsStateType {
return { return {
conversationLookup: {}, conversationLookup: {},
messageCollection: 'stuff',
showArchived: false, showArchived: false,
}; };
} }
@ -293,17 +291,10 @@ 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 { return {
...state, ...state,
selectedConversation, selectedConversation,
showArchived, showArchived,
messageCollection: 'afgjvhbrgvkhbrg',
conversationLookup: { conversationLookup: {
...conversationLookup, ...conversationLookup,
[id]: data, [id]: data,

@ -0,0 +1,6 @@
export const reducer = (state: any, action: any) => {
console.log(`[vince][redux] Action: `, action);
return state;
}

@ -37,7 +37,6 @@ export type SearchStateType = {
}; };
// Actions // Actions
type SearchResultsPayloadType = { type SearchResultsPayloadType = {
query: string; query: string;
normalizedPhoneNumber?: string; normalizedPhoneNumber?: string;
@ -158,6 +157,41 @@ const getMessageProps = (messages: Array<MessageType>) => {
}); });
}; };
async function doGetMessages(
query: string,
options: SearchOptions
): Promise<SearchResultsPayloadType> {
const { regionCode } = options;
const [discussions, messages] = await Promise.all([
queryConversationsAndContacts(query, options),
queryMessages(query),
]);
const { conversations, contacts } = discussions;
const filteredMessages = messages.filter(message => message !== undefined);
let messageSet = [];
if (filteredMessages && !filteredMessages.length) {
messageSet = filteredMessages.map(message => {
const model = getMessageModel(message);
return model.propsForMessage;
});
}
return {
query,
normalizedPhoneNumber: normalize(query, { regionCode }),
conversations,
contacts,
messages: messageSet,
};
}
async function queryMessages(query: string) { async function queryMessages(query: string) {
try { try {
const normalized = cleanSearchTerm(query); const normalized = cleanSearchTerm(query);

@ -7,14 +7,20 @@ import {
} from './ducks/conversations'; } from './ducks/conversations';
import { reducer as user, UserStateType } from './ducks/user'; import { reducer as user, UserStateType } from './ducks/user';
import { reducer as messages } from './ducks/search';
export type StateType = { export type StateType = {
search: SearchStateType; search: SearchStateType;
messages: any;
conversations: ConversationsStateType; conversations: ConversationsStateType;
user: UserStateType; user: UserStateType;
}; };
export const reducers = { export const reducers = {
search, search,
messages,
conversations, conversations,
user, user,
}; };

@ -3,7 +3,15 @@ import { mapDispatchToProps } from '../actions';
import { SessionConversation } from '../../components/session/SessionConversation'; import { SessionConversation } from '../../components/session/SessionConversation';
import { StateType } from '../reducer'; import { StateType } from '../reducer';
import { getSessionConversationInfo } from '../selectors/conversations'; import { getQuery, getSearchResults, isSearching } from '../selectors/search';
import {
getIntl,
getIsSecondaryDevice,
getRegionCode,
getUserNumber,
} from '../selectors/user';
const mapStateToProps = (state: StateType) => { const mapStateToProps = (state: StateType) => {
//const conversationInfo = getSessionConversationInfo(state); //const conversationInfo = getSessionConversationInfo(state);

Loading…
Cancel
Save