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
This commit is contained in:
parent
3f0354f09e
commit
72b7e4ec34
6 changed files with 162 additions and 54 deletions
|
@ -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": {
|
||||
"message": "$name$ set the timer to $time$.",
|
||||
"description": "Message displayed when someone else changes the message expiration timer in a conversation.",
|
||||
|
|
|
@ -8,6 +8,12 @@
|
|||
console.log(e);
|
||||
};
|
||||
|
||||
window.wrapDeferred = function(deferred) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
deferred.then(resolve, reject);
|
||||
});
|
||||
};
|
||||
|
||||
console.log('background page reloaded');
|
||||
console.log('environment:', window.config.environment);
|
||||
|
||||
|
@ -377,38 +383,58 @@
|
|||
|
||||
return ConversationController.getOrCreateAndWait(id, 'private')
|
||||
.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
|
||||
// activeAt is null, then this contact has been purposefully hidden.
|
||||
if (activeAt !== null) {
|
||||
activeAt = activeAt || Date.now();
|
||||
}
|
||||
// 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.
|
||||
if (activeAt !== null) {
|
||||
activeAt = activeAt || Date.now();
|
||||
}
|
||||
|
||||
if (details.profileKey) {
|
||||
conversation.set({profileKey: details.profileKey});
|
||||
if (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,
|
||||
color: details.color,
|
||||
active_at: activeAt,
|
||||
}).then(resolve, reject);
|
||||
}).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);
|
||||
}
|
||||
|
||||
return wrapDeferred(conversation.save({
|
||||
name: details.name,
|
||||
avatar: details.avatar,
|
||||
color: details.color,
|
||||
active_at: activeAt,
|
||||
})).then(function() {
|
||||
// this needs to be inline to get access to conversation model
|
||||
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(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)
|
||||
.catch(function(error) {
|
||||
console.log(
|
||||
|
@ -437,11 +463,22 @@
|
|||
if (activeAt !== null) {
|
||||
updates.active_at = activeAt || Date.now();
|
||||
}
|
||||
updates.left = false;
|
||||
} else {
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -3,8 +3,27 @@
|
|||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
window.Whisper = window.Whisper || {};
|
||||
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));
|
||||
},
|
||||
|
||||
updateExpirationTimer: function(expireTimer, source, received_at) {
|
||||
if (!expireTimer) { expireTimer = null; }
|
||||
updateExpirationTimer: function(expireTimer, source, received_at, options) {
|
||||
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();
|
||||
var timestamp = received_at || Date.now();
|
||||
this.save({ expireTimer: expireTimer });
|
||||
|
||||
var message = this.messageCollection.add({
|
||||
conversationId : this.id,
|
||||
type : received_at ? 'incoming' : 'outgoing',
|
||||
|
@ -681,7 +698,8 @@
|
|||
flags : textsecure.protobuf.DataMessage.Flags.EXPIRATION_TIMER_UPDATE,
|
||||
expirationTimerUpdate : {
|
||||
expireTimer : expireTimer,
|
||||
source : source
|
||||
source : source,
|
||||
fromSync : options.fromSync,
|
||||
}
|
||||
});
|
||||
if (this.isPrivate()) {
|
||||
|
@ -690,8 +708,16 @@
|
|||
if (message.isOutgoing()) {
|
||||
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;
|
||||
if (this.get('type') == 'private') {
|
||||
sendFunc = textsecure.messaging.sendExpirationTimerUpdateToNumber;
|
||||
|
@ -703,9 +729,16 @@
|
|||
if (this.get('profileSharing')) {
|
||||
profileKey = storage.get('profileKey');
|
||||
}
|
||||
message.send(sendFunc(this.get('id'), this.get('expireTimer'), message.get('sent_at'), profileKey));
|
||||
}
|
||||
return message;
|
||||
var promise = sendFunc(this.get('id'),
|
||||
this.get('expireTimer'),
|
||||
message.get('sent_at'),
|
||||
profileKey
|
||||
);
|
||||
|
||||
return message.send(promise).then(function() {
|
||||
return message;
|
||||
});
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
isSearchable: function() {
|
||||
|
|
|
@ -82,13 +82,19 @@
|
|||
render_attributes: function() {
|
||||
var seconds = this.model.get('expirationTimerUpdate').expireTimer;
|
||||
var timerMessage;
|
||||
if (this.conversation.id === textsecure.storage.user.getNumber()) {
|
||||
timerMessage = i18n('youChangedTheTimer',
|
||||
Whisper.ExpirationTimerOptions.getName(seconds));
|
||||
|
||||
var timerUpdate = this.model.get('expirationTimerUpdate');
|
||||
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 {
|
||||
timerMessage = i18n('theyChangedTheTimer', [
|
||||
this.conversation.getTitle(),
|
||||
Whisper.ExpirationTimerOptions.getName(seconds)]);
|
||||
prettySeconds,
|
||||
]);
|
||||
}
|
||||
return { content: timerMessage };
|
||||
}
|
||||
|
|
|
@ -194,12 +194,14 @@ message ContactDetails {
|
|||
optional uint32 length = 2;
|
||||
}
|
||||
|
||||
optional string number = 1;
|
||||
optional string name = 2;
|
||||
optional Avatar avatar = 3;
|
||||
optional string color = 4;
|
||||
optional Verified verified = 5;
|
||||
optional bytes profileKey = 6;
|
||||
optional string number = 1;
|
||||
optional string name = 2;
|
||||
optional Avatar avatar = 3;
|
||||
optional string color = 4;
|
||||
optional Verified verified = 5;
|
||||
optional bytes profileKey = 6;
|
||||
optional bool blocked = 7;
|
||||
optional uint32 expireTimer = 8;
|
||||
}
|
||||
|
||||
message GroupDetails {
|
||||
|
@ -208,9 +210,10 @@ message GroupDetails {
|
|||
optional uint32 length = 2;
|
||||
}
|
||||
|
||||
optional bytes id = 1;
|
||||
optional string name = 2;
|
||||
repeated string members = 3;
|
||||
optional Avatar avatar = 4;
|
||||
optional bool active = 5 [default = true];
|
||||
optional bytes id = 1;
|
||||
optional string name = 2;
|
||||
repeated string members = 3;
|
||||
optional Avatar avatar = 4;
|
||||
optional bool active = 5 [default = true];
|
||||
optional uint32 expireTimer = 6;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue