Process expireTimer and block status along with contact/group sync (#1980)

* Mark group as left = false if it is active in contact sync

* Handle expireTimer + blocked state along with contact/group sync
pull/1/head
Scott Nonnenberg 7 years ago committed by GitHub
parent 3f0354f09e
commit 72b7e4ec34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -748,6 +748,16 @@
} }
} }
}, },
"timerSetOnSync": {
"message": "Updating timer to $time$.",
"description": "Message displayed when timer is set on initial link of desktop device.",
"placeholders": {
"time": {
"content": "$1",
"example": "10m"
}
}
},
"theyChangedTheTimer": { "theyChangedTheTimer": {
"message": "$name$ set the timer to $time$.", "message": "$name$ set the timer to $time$.",
"description": "Message displayed when someone else changes the message expiration timer in a conversation.", "description": "Message displayed when someone else changes the message expiration timer in a conversation.",

@ -8,6 +8,12 @@
console.log(e); console.log(e);
}; };
window.wrapDeferred = function(deferred) {
return new Promise(function(resolve, reject) {
deferred.then(resolve, reject);
});
};
console.log('background page reloaded'); console.log('background page reloaded');
console.log('environment:', window.config.environment); console.log('environment:', window.config.environment);
@ -377,38 +383,58 @@
return ConversationController.getOrCreateAndWait(id, 'private') return ConversationController.getOrCreateAndWait(id, 'private')
.then(function(conversation) { .then(function(conversation) {
return new Promise(function(resolve, reject) { var activeAt = conversation.get('active_at');
var activeAt = conversation.get('active_at');
// The idea is to make any new contact show up in the left pane. If // The idea is to make any new contact show up in the left pane. If
// activeAt is null, then this contact has been purposefully hidden. // activeAt is null, then this contact has been purposefully hidden.
if (activeAt !== null) { if (activeAt !== null) {
activeAt = activeAt || Date.now(); activeAt = activeAt || Date.now();
} }
if (details.profileKey) { if (details.profileKey) {
conversation.set({profileKey: details.profileKey}); conversation.set({profileKey: details.profileKey});
}
if (typeof details.blocked !== 'undefined') {
if (details.blocked) {
storage.addBlockedNumber(id);
} else {
storage.removeBlockedNumber(id);
} }
conversation.save({ }
name: details.name,
avatar: details.avatar, return wrapDeferred(conversation.save({
color: details.color, name: details.name,
active_at: activeAt, avatar: details.avatar,
}).then(resolve, reject); color: details.color,
}).then(function() { active_at: activeAt,
if (details.verified) { })).then(function() {
var verified = details.verified; // this needs to be inline to get access to conversation model
var ev = new Event('verified'); if (typeof details.expireTimer !== 'undefined') {
ev.verified = { var source = textsecure.storage.user.getNumber();
state: verified.state, var receivedAt = Date.now();
destination: verified.destination, return conversation.updateExpirationTimer(
identityKey: verified.identityKey.toArrayBuffer(), details.expireTimer,
}; source,
ev.viaContactSync = true; receivedAt,
return onVerified(ev); {fromSync: true}
);
} }
}); });
}) })
.then(function() {
if (details.verified) {
var verified = details.verified;
var ev = new Event('verified');
ev.verified = {
state: verified.state,
destination: verified.destination,
identityKey: verified.identityKey.toArrayBuffer(),
};
ev.viaContactSync = true;
return onVerified(ev);
}
})
.then(ev.confirm) .then(ev.confirm)
.catch(function(error) { .catch(function(error) {
console.log( console.log(
@ -437,11 +463,22 @@
if (activeAt !== null) { if (activeAt !== null) {
updates.active_at = activeAt || Date.now(); updates.active_at = activeAt || Date.now();
} }
updates.left = false;
} else { } else {
updates.left = true; updates.left = true;
} }
return new Promise(function(resolve, reject) {
conversation.save(updates).then(resolve, reject); return wrapDeferred(conversation.save(updates)).then(function() {
if (typeof details.expireTimer !== 'undefined') {
var source = textsecure.storage.user.getNumber();
var receivedAt = Date.now();
return conversation.updateExpirationTimer(
details.expireTimer,
source,
receivedAt,
{fromSync: true}
);
}
}).then(ev.confirm); }).then(ev.confirm);
}); });
} }

@ -3,8 +3,27 @@
*/ */
(function () { (function () {
'use strict'; 'use strict';
window.Whisper = window.Whisper || {};
storage.isBlocked = function(number) { storage.isBlocked = function(number) {
return storage.get('blocked', []).indexOf(number) >= 0; var numbers = storage.get('blocked', []);
return _.include(numbers, number);
};
storage.addBlockedNumber = function(number) {
var numbers = storage.get('blocked', []);
if (_.include(numbers, number)) {
return;
}
console.log('adding', number, 'to blocked list');
storage.put('blocked', numbers.concat(number));
};
storage.removeBlockedNumber = function(number) {
var numbers = storage.get('blocked', []);
if (!_.include(numbers, number)) {
return;
}
console.log('removing', number, 'from blocked list');
storage.put('blocked', _.without(numbers, number));
}; };
})(); })();

@ -668,11 +668,28 @@
}.bind(this)); }.bind(this));
}, },
updateExpirationTimer: function(expireTimer, source, received_at) { updateExpirationTimer: function(expireTimer, source, received_at, options) {
if (!expireTimer) { expireTimer = null; } options = options || {};
_.defaults(options, {fromSync: false});
if (!expireTimer) {
expireTimer = null;
}
if (this.get('expireTimer') === expireTimer
|| (!expireTimer && !this.get('expireTimer'))) {
return;
}
console.log(
'Updating expireTimer for conversation',
this.idForLogging(),
'via',
source
);
source = source || textsecure.storage.user.getNumber(); source = source || textsecure.storage.user.getNumber();
var timestamp = received_at || Date.now(); var timestamp = received_at || Date.now();
this.save({ expireTimer: expireTimer });
var message = this.messageCollection.add({ var message = this.messageCollection.add({
conversationId : this.id, conversationId : this.id,
type : received_at ? 'incoming' : 'outgoing', type : received_at ? 'incoming' : 'outgoing',
@ -681,7 +698,8 @@
flags : textsecure.protobuf.DataMessage.Flags.EXPIRATION_TIMER_UPDATE, flags : textsecure.protobuf.DataMessage.Flags.EXPIRATION_TIMER_UPDATE,
expirationTimerUpdate : { expirationTimerUpdate : {
expireTimer : expireTimer, expireTimer : expireTimer,
source : source source : source,
fromSync : options.fromSync,
} }
}); });
if (this.isPrivate()) { if (this.isPrivate()) {
@ -690,8 +708,16 @@
if (message.isOutgoing()) { if (message.isOutgoing()) {
message.set({recipients: this.getRecipients() }); message.set({recipients: this.getRecipients() });
} }
message.save();
if (message.isOutgoing()) { // outgoing update, send it to the number/group return Promise.all([
wrapDeferred(message.save()),
wrapDeferred(this.save({ expireTimer: expireTimer })),
]).then(function() {
if (message.isIncoming()) {
return message;
}
// change was made locally, send it to the number/group
var sendFunc; var sendFunc;
if (this.get('type') == 'private') { if (this.get('type') == 'private') {
sendFunc = textsecure.messaging.sendExpirationTimerUpdateToNumber; sendFunc = textsecure.messaging.sendExpirationTimerUpdateToNumber;
@ -703,9 +729,16 @@
if (this.get('profileSharing')) { if (this.get('profileSharing')) {
profileKey = storage.get('profileKey'); profileKey = storage.get('profileKey');
} }
message.send(sendFunc(this.get('id'), this.get('expireTimer'), message.get('sent_at'), profileKey)); var promise = sendFunc(this.get('id'),
} this.get('expireTimer'),
return message; message.get('sent_at'),
profileKey
);
return message.send(promise).then(function() {
return message;
});
}.bind(this));
}, },
isSearchable: function() { isSearchable: function() {

@ -82,13 +82,19 @@
render_attributes: function() { render_attributes: function() {
var seconds = this.model.get('expirationTimerUpdate').expireTimer; var seconds = this.model.get('expirationTimerUpdate').expireTimer;
var timerMessage; var timerMessage;
if (this.conversation.id === textsecure.storage.user.getNumber()) {
timerMessage = i18n('youChangedTheTimer', var timerUpdate = this.model.get('expirationTimerUpdate');
Whisper.ExpirationTimerOptions.getName(seconds)); var prettySeconds = Whisper.ExpirationTimerOptions.getName(seconds);
if (timerUpdate && timerUpdate.fromSync) {
timerMessage = i18n('timerSetOnSync', prettySeconds);
} else if (this.conversation.id === textsecure.storage.user.getNumber()) {
timerMessage = i18n('youChangedTheTimer', prettySeconds);
} else { } else {
timerMessage = i18n('theyChangedTheTimer', [ timerMessage = i18n('theyChangedTheTimer', [
this.conversation.getTitle(), this.conversation.getTitle(),
Whisper.ExpirationTimerOptions.getName(seconds)]); prettySeconds,
]);
} }
return { content: timerMessage }; return { content: timerMessage };
} }

@ -194,12 +194,14 @@ message ContactDetails {
optional uint32 length = 2; optional uint32 length = 2;
} }
optional string number = 1; optional string number = 1;
optional string name = 2; optional string name = 2;
optional Avatar avatar = 3; optional Avatar avatar = 3;
optional string color = 4; optional string color = 4;
optional Verified verified = 5; optional Verified verified = 5;
optional bytes profileKey = 6; optional bytes profileKey = 6;
optional bool blocked = 7;
optional uint32 expireTimer = 8;
} }
message GroupDetails { message GroupDetails {
@ -208,9 +210,10 @@ message GroupDetails {
optional uint32 length = 2; optional uint32 length = 2;
} }
optional bytes id = 1; optional bytes id = 1;
optional string name = 2; optional string name = 2;
repeated string members = 3; repeated string members = 3;
optional Avatar avatar = 4; optional Avatar avatar = 4;
optional bool active = 5 [default = true]; optional bool active = 5 [default = true];
optional uint32 expireTimer = 6;
} }

Loading…
Cancel
Save