Added syncing accepting of contact between running instances.

pull/2000/head
Warrick Corfe-Tan 4 years ago
parent 9e0f128fc6
commit 4ad14e4c5b

@ -1600,9 +1600,14 @@ function updateConversation(data) {
type, type,
members, members,
name, name,
isApproved,
profileName, profileName,
} = data; } = data;
console.log({ usrData: data });
console.log({ usrDataTrace: console.trace() });
console.log('usrData@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@');
globalInstance globalInstance
.prepare( .prepare(
`UPDATE ${CONVERSATIONS_TABLE} SET `UPDATE ${CONVERSATIONS_TABLE} SET
@ -1612,6 +1617,7 @@ function updateConversation(data) {
type = $type, type = $type,
members = $members, members = $members,
name = $name, name = $name,
isApproved = $isApproved,
profileName = $profileName profileName = $profileName
WHERE id = $id;` WHERE id = $id;`
) )
@ -1623,6 +1629,7 @@ function updateConversation(data) {
type, type,
members: members ? members.join(' ') : null, members: members ? members.join(' ') : null,
name, name,
isApproved,
profileName, profileName,
}); });
} }

@ -30,7 +30,7 @@ import { ConversationNotificationSettingType } from '../models/conversation';
import { Flex } from './basic/Flex'; import { Flex } from './basic/Flex';
import { SessionButton, SessionButtonColor } from './session/SessionButton'; import { SessionButton, SessionButtonColor } from './session/SessionButton';
import { getConversationById } from '../data/data'; import { getConversationById } from '../data/data';
import { getConversationController } from '../session/conversations'; import { syncConfigurationIfNeeded } from '../session/utils/syncUtils';
// tslint:disable-next-line: no-empty-interface // tslint:disable-next-line: no-empty-interface
export interface ConversationListItemProps extends ReduxConversationType {} export interface ConversationListItemProps extends ReduxConversationType {}
@ -287,7 +287,10 @@ const ConversationListItem = (props: Props) => {
* deletes the conversation * deletes the conversation
*/ */
const handleConversationDecline = async () => { const handleConversationDecline = async () => {
await getConversationController().deleteContact(conversationId); // const convoToDecline = await getConversationById(conversationId);
// convoToDecline?.setIsApproved(false);
// await getConversationController().deleteContact(conversationId); // TODO: might be unnecessary
console.warn('decline');
}; };
/** /**
@ -295,12 +298,12 @@ const ConversationListItem = (props: Props) => {
*/ */
const handleConversationAccept = async () => { const handleConversationAccept = async () => {
const conversationToApprove = await getConversationById(conversationId); const conversationToApprove = await getConversationById(conversationId);
conversationToApprove?.setIsApproved(true); await conversationToApprove?.setIsApproved(true);
console.warn('convo marked as approved'); console.warn({ convoAfterSetIsApproved: conversationToApprove });
console.warn({ convo: conversationToApprove });
// TODO: Send sync message to other devices. Using config message // TODO: Send sync message to other devices. Using config message
await syncConfigurationIfNeeded(true);
}; };
return ( return (

@ -85,22 +85,26 @@ export class LeftPaneMessageSection extends React.Component<Props, State> {
public renderRow = ({ index, key, style }: RowRendererParamsType): JSX.Element | null => { public renderRow = ({ index, key, style }: RowRendererParamsType): JSX.Element | null => {
const { conversations } = this.props; const { conversations } = this.props;
const approvedConversations = conversations?.filter(c => c.isApproved === true); const approvedConversations = conversations?.filter(c => Boolean(c.isApproved) === true);
if (!conversations || !approvedConversations) { if (!conversations || !approvedConversations) {
throw new Error('renderRow: Tried to render without conversations'); throw new Error('renderRow: Tried to render without conversations');
} }
// const conversation = conversations[index];
// TODO: make this only filtered when the setting is enabled
const messageRequestsEnabled =
window.inboxStore?.getState().userConfig.messageRequests === true;
let conversation; let conversation;
if (approvedConversations?.length) { if (approvedConversations?.length) {
conversation = approvedConversations[index]; conversation = approvedConversations[index];
} }
// TODO: need to confirm whats best here. if (!conversation) {
if ( return null;
!conversation || }
conversation?.isApproved === undefined ||
conversation.isApproved === false // TODO: need to confirm what default setting is best here.
) { if (messageRequestsEnabled && !Boolean(conversation.isApproved)) {
return null; return null;
} }
return <MemoConversationListItemWithDetails key={key} style={style} {...conversation} />; return <MemoConversationListItemWithDetails key={key} style={style} {...conversation} />;
@ -120,21 +124,9 @@ export class LeftPaneMessageSection extends React.Component<Props, State> {
// TODO: make selectors for this instead. // TODO: make selectors for this instead.
// TODO: only filter conversations if setting for requests is applied // TODO: only filter conversations if setting for requests is applied
const approvedConversations = conversations.filter(c => c.isApproved === true);
const messageRequestsEnabled =
window.inboxStore?.getState().userConfig.messageRequests === true;
const conversationsForList = messageRequestsEnabled ? approvedConversations : conversations;
if (!this.state.approvedConversations.length) {
this.setState({
approvedConversations: conversationsForList,
});
}
console.warn({ conversationsForList });
// const length = conversations.length; // TODO: readjust to be approved length as only approved convos will show here.
const length = conversationsForList.length; const length = this.props.conversations ? this.props.conversations.length : 0;
const listKey = 0; const listKey = 0;
// Note: conversations is not a known prop for List, but it is required to ensure that // Note: conversations is not a known prop for List, but it is required to ensure that
@ -146,8 +138,8 @@ export class LeftPaneMessageSection extends React.Component<Props, State> {
{({ height, width }) => ( {({ height, width }) => (
<List <List
className="module-left-pane__virtual-list" className="module-left-pane__virtual-list"
conversations={this.state.approvedConversations} // conversations={this.state.approvedConversations}
// conversations={[]} conversations={this.props.conversations}
height={height} height={height}
rowCount={length} rowCount={length}
rowHeight={64} rowHeight={64}

@ -522,7 +522,8 @@ export async function getConversationById(id: string): Promise<ConversationModel
} }
export async function updateConversation(data: ReduxConversationType): Promise<void> { export async function updateConversation(data: ReduxConversationType): Promise<void> {
await channels.updateConversation(data); const cleanedData = _cleanData(data);
await channels.updateConversation(cleanedData);
} }
export async function removeConversation(id: string): Promise<void> { export async function removeConversation(id: string): Promise<void> {
@ -601,7 +602,6 @@ export async function cleanLastHashes(): Promise<void> {
await channels.cleanLastHashes(); await channels.cleanLastHashes();
} }
// TODO: Strictly type the following
export async function saveSeenMessageHashes( export async function saveSeenMessageHashes(
data: Array<{ data: Array<{
expiresAt: number; expiresAt: number;

@ -176,6 +176,7 @@ export const fillConvoAttributesWithDefaults = (
triggerNotificationsFor: 'all', // if the settings is not set in the db, this is the default triggerNotificationsFor: 'all', // if the settings is not set in the db, this is the default
isTrustedForAttachmentDownload: false, // we don't trust a contact until we say so isTrustedForAttachmentDownload: false, // we don't trust a contact until we say so
isPinned: false, isPinned: false,
isApproved: false,
}); });
}; };
@ -777,7 +778,6 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
const chatMessagePrivate = new VisibleMessage(chatMessageParams); const chatMessagePrivate = new VisibleMessage(chatMessageParams);
await getMessageQueue().sendToPubKey(destinationPubkey, chatMessagePrivate); await getMessageQueue().sendToPubKey(destinationPubkey, chatMessagePrivate);
// this.setIsApproved(true); // consider the conversation approved even if the message fails to send
return; return;
} }
@ -1389,21 +1389,12 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
} }
public async setIsApproved(value: boolean) { public async setIsApproved(value: boolean) {
console.warn(`Setting ${this.attributes.nickname} isApproved to:: ${value}`);
if (value !== this.get('isApproved')) { if (value !== this.get('isApproved')) {
console.warn(`Setting ${this.attributes.profileName} isApproved to:: ${value}`);
this.set({ this.set({
isApproved: value, isApproved: value,
}); });
await this.commit(); await this.commit();
if (window?.inboxStore) {
window.inboxStore?.dispatch(
conversationChanged({
id: this.id,
data: this.getConversationModelProps(),
})
);
}
} }
} }

@ -1,5 +1,5 @@
import _ from 'lodash'; import _ from 'lodash';
import { createOrUpdateItem, getItemById, hasSyncedInitialConfigurationItem } from '../data/data'; import { createOrUpdateItem } from '../data/data';
import { ConversationTypeEnum } from '../models/conversation'; import { ConversationTypeEnum } from '../models/conversation';
import { import {
joinOpenGroupV2WithUIEvents, joinOpenGroupV2WithUIEvents,
@ -53,14 +53,16 @@ async function handleGroupsAndContactsFromConfigMessage(
envelope: EnvelopePlus, envelope: EnvelopePlus,
configMessage: SignalService.ConfigurationMessage configMessage: SignalService.ConfigurationMessage
) { ) {
const didWeHandleAConfigurationMessageAlready = // const didWeHandleAConfigurationMessageAlready =
(await getItemById(hasSyncedInitialConfigurationItem))?.value || false; // (await getItemById(hasSyncedInitialConfigurationItem))?.value || false;
if (didWeHandleAConfigurationMessageAlready) {
window?.log?.info( // TODO: debug
'Dropping configuration contacts/groups change as we already handled one... ' // if (didWeHandleAConfigurationMessageAlready) {
); // window?.log?.info(
return; // 'Dropping configuration contacts/groups change as we already handled one... '
} // );
// return;
// }
await createOrUpdateItem({ await createOrUpdateItem({
id: 'hasSyncedInitialConfigurationItem', id: 'hasSyncedInitialConfigurationItem',
value: true, value: true,
@ -125,6 +127,7 @@ async function handleGroupsAndContactsFromConfigMessage(
}; };
// updateProfile will do a commit for us // updateProfile will do a commit for us
contactConvo.set('active_at', _.toNumber(envelope.timestamp)); contactConvo.set('active_at', _.toNumber(envelope.timestamp));
contactConvo.setIsApproved(Boolean(c.isApproved));
await updateProfileOneAtATime(contactConvo, profile, c.profileKey); await updateProfileOneAtATime(contactConvo, profile, c.profileKey);
} catch (e) { } catch (e) {

@ -377,6 +377,7 @@ export async function innerHandleContentMessage(
} }
if (content.configurationMessage) { if (content.configurationMessage) {
// this one can be quite long (downloads profilePictures and everything, is do not block) // this one can be quite long (downloads profilePictures and everything, is do not block)
console.warn('@@config message received. contentmessage.ts');
void handleConfigurationMessage( void handleConfigurationMessage(
envelope, envelope,
content.configurationMessage as SignalService.ConfigurationMessage content.configurationMessage as SignalService.ConfigurationMessage

@ -99,7 +99,6 @@ export class ConversationController {
const create = async () => { const create = async () => {
try { try {
debugger;
await saveConversation(conversation.attributes); await saveConversation(conversation.attributes);
} catch (error) { } catch (error) {
window?.log?.error( window?.log?.error(

@ -1,5 +1,6 @@
import { import {
createOrUpdateItem, createOrUpdateItem,
getAllConversations,
getItemById, getItemById,
getLatestClosedGroupEncryptionKeyPair, getLatestClosedGroupEncryptionKeyPair,
} from '../../../ts/data/data'; } from '../../../ts/data/data';
@ -36,16 +37,24 @@ const getLastSyncTimestampFromDb = async (): Promise<number | undefined> =>
const writeLastSyncTimestampToDb = async (timestamp: number) => const writeLastSyncTimestampToDb = async (timestamp: number) =>
createOrUpdateItem({ id: ITEM_ID_LAST_SYNC_TIMESTAMP, value: timestamp }); createOrUpdateItem({ id: ITEM_ID_LAST_SYNC_TIMESTAMP, value: timestamp });
export const syncConfigurationIfNeeded = async () => { /**
* Syncs usre configuration with other devices linked to this user.
* @param force Bypass duration time limit for sending sync messages
* @returns
*/
export const syncConfigurationIfNeeded = async (force: boolean = false) => {
const lastSyncedTimestamp = (await getLastSyncTimestampFromDb()) || 0; const lastSyncedTimestamp = (await getLastSyncTimestampFromDb()) || 0;
const now = Date.now(); const now = Date.now();
// if the last sync was less than 2 days before, return early. // if the last sync was less than 2 days before, return early.
if (Math.abs(now - lastSyncedTimestamp) < DURATION.DAYS * 7) { if (!force && Math.abs(now - lastSyncedTimestamp) < DURATION.DAYS * 7) {
return; return;
} }
const allConvos = getConversationController().getConversations(); const allConvos = await (await getAllConversations()).models;
console.warn({ test: allConvos[0].attributes.isApproved });
// const configMessage = await getCurrentConfigurationMessage(allConvos);
const configMessage = await getCurrentConfigurationMessage(allConvos); const configMessage = await getCurrentConfigurationMessage(allConvos);
try { try {
// window?.log?.info('syncConfigurationIfNeeded with', configMessage); // window?.log?.info('syncConfigurationIfNeeded with', configMessage);
@ -191,6 +200,7 @@ const getValidContacts = (convos: Array<ConversationModel>) => {
displayName: c.getLokiProfile()?.displayName, displayName: c.getLokiProfile()?.displayName,
profilePictureURL: c.get('avatarPointer'), profilePictureURL: c.get('avatarPointer'),
profileKey: !profileKeyForContact?.length ? undefined : profileKeyForContact, profileKey: !profileKeyForContact?.length ? undefined : profileKeyForContact,
isApproved: c.isApproved(),
}); });
} catch (e) { } catch (e) {
window?.log.warn('getValidContacts', e); window?.log.warn('getValidContacts', e);

Loading…
Cancel
Save