Add items to conversation history when user verifies/unverifies

FREEBIE
pull/749/head
Scott Nonnenberg 8 years ago
parent 02973372aa
commit 1cf9289b1a

@ -33,6 +33,26 @@
} }
} }
}, },
"youMarkedAsVerified": {
"message": "You marked $name$ as verified.",
"description": "Shown in the conversation history when the user marks a contact as verified.",
"placeholders": {
"name": {
"content": "$1",
"example": "Bob"
}
}
},
"youMarkedAsNotVerified": {
"message": "You marked $name$ as not verified.",
"description": "Shown in the conversation history when the user marks a contact as verified, whether on the safety number screen or by dismissing a banner or dialog.",
"placeholders": {
"name": {
"content": "$1",
"example": "Bob"
}
}
},
"changedSinceVerifiedMultiple": { "changedSinceVerifiedMultiple": {
"message": "Your safety numbers with multiple group members have changed since you last verified.", "message": "Your safety numbers with multiple group members have changed since you last verified.",
"description": "Shown on confirmation dialog when user attempts to send a message" "description": "Shown on confirmation dialog when user attempts to send a message"

@ -193,6 +193,9 @@
<script type='text/x-tmpl-mustache' id='keychange'> <script type='text/x-tmpl-mustache' id='keychange'>
<span class='content' dir='auto'>{{ content }}</span> <span class='content' dir='auto'>{{ content }}</span>
</script> </script>
<script type='text/x-tmpl-mustache' id='verified-change'>
<span class='content' dir='auto'><span class='{{ icon }} icon'></span> {{ content }}</span>
</script>
<script type='text/x-tmpl-mustache' id='message'> <script type='text/x-tmpl-mustache' id='message'>
{{> avatar }} {{> avatar }}
<div class='bubble {{ avatar.color }}'> <div class='bubble {{ avatar.color }}'>

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4zm0 10.99h7c-.53 4.12-3.28 7.79-7 8.94V12H5V6.3l7-3.11v8.8z"/></svg>

After

Width:  |  Height:  |  Size: 223 B

@ -103,6 +103,11 @@
}); });
}); });
}, },
getAllGroupsInvolvingId: function(id) {
return conversations.filter(function(conversation) {
return !conversation.isPrivate() && conversation.hasMember(id);
});
},
updateInbox: function() { updateInbox: function() {
return conversations.fetchActive(); return conversations.fetchActive();
} }

@ -98,6 +98,9 @@
// return textsecure.storage.protocol.setVerified(this.id, DEFAULT).then(function() { // return textsecure.storage.protocol.setVerified(this.id, DEFAULT).then(function() {
return updateTrustStore(this.id, DEFAULT).then(function() { return updateTrustStore(this.id, DEFAULT).then(function() {
return this.save({verified: DEFAULT}); return this.save({verified: DEFAULT});
}.bind(this)).then(function() {
// TODO: send sync message? add a parameter to tell us if this is via a sync message?
this.addVerifiedChange(this.id, false);
}.bind(this)); }.bind(this));
}, },
setVerified: function() { setVerified: function() {
@ -114,6 +117,9 @@
// return textsecure.storage.protocol.setVerified(this.id, VERIFIED).then(function() { // return textsecure.storage.protocol.setVerified(this.id, VERIFIED).then(function() {
return updateTrustStore(this.id, VERIFIED).then(function() { return updateTrustStore(this.id, VERIFIED).then(function() {
return this.save({verified: VERIFIED}); return this.save({verified: VERIFIED});
}.bind(this)).then(function() {
// TODO: send sync message? add a parameter to tell us if this is via a sync message?
this.addVerifiedChange(this.id, true);
}.bind(this)); }.bind(this));
}, },
isVerified: function() { isVerified: function() {
@ -235,7 +241,7 @@
}, },
addKeyChange: function(id) { addKeyChange: function(id) {
console.log('adding key change advisory for', this.id, this.get('timestamp')); console.log('adding key change advisory for', this.id, id, this.get('timestamp'));
var timestamp = Date.now(); var timestamp = Date.now();
var message = new Whisper.Message({ var message = new Whisper.Message({
conversationId : this.id, conversationId : this.id,
@ -246,6 +252,27 @@
}); });
message.save().then(this.trigger.bind(this,'newmessage', message)); message.save().then(this.trigger.bind(this,'newmessage', message));
}, },
addVerifiedChange: function(id, verified) {
console.log('adding verified change advisory for', this.id, id, this.get('timestamp'));
var timestamp = Date.now();
var message = new Whisper.Message({
conversationId : this.id,
type : 'verified-change',
// why is sent_at set to this.get('timestamp?')
sent_at : this.get('timestamp'),
received_at : timestamp,
verifiedChanged : id,
verified : verified
});
message.save().then(this.trigger.bind(this,'newmessage', message));
if (this.isPrivate()) {
var groups = ConversationController.getAllGroupsInvolvingId(id);
_.forEach(groups, function(group) {
group.addVerifiedChange(id, verified);
});
}
},
onReadMessage: function(message) { onReadMessage: function(message) {
if (this.messageCollection.get(message.id)) { if (this.messageCollection.get(message.id)) {
@ -382,6 +409,9 @@
var collection = new Whisper.MessageCollection(); var collection = new Whisper.MessageCollection();
return collection.fetchConversation(this.id, 1).then(function() { return collection.fetchConversation(this.id, 1).then(function() {
var lastMessage = collection.at(0); var lastMessage = collection.at(0);
if (lastMessage.get('type') === 'verified-change') {
return;
}
if (lastMessage) { if (lastMessage) {
this.set({ this.set({
lastMessage : lastMessage.getNotificationText(), lastMessage : lastMessage.getNotificationText(),
@ -551,6 +581,9 @@
return this.messageCollection.fetchConversation(this.id, null, this.get('unreadCount')); return this.messageCollection.fetchConversation(this.id, null, this.get('unreadCount'));
}, },
hasMember: function(number) {
return _.contains(this.get('members'), number);
},
fetchContacts: function(options) { fetchContacts: function(options) {
return new Promise(function(resolve) { return new Promise(function(resolve) {
if (this.isPrivate()) { if (this.isPrivate()) {

@ -182,6 +182,18 @@
} }
return this.modelForKeyChange; return this.modelForKeyChange;
}, },
getModelForVerifiedChange: function() {
var id = this.get('verifiedChanged');
if (!this.modelForVerifiedChange) {
var c = ConversationController.get(id);
if (!c) {
c = ConversationController.create({ id: id, type: 'private' });
c.fetch();
}
this.modelForVerifiedChange = c;
}
return this.modelForVerifiedChange;
},
isOutgoing: function() { isOutgoing: function() {
return this.get('type') === 'outgoing'; return this.get('type') === 'outgoing';
}, },

@ -185,14 +185,16 @@
'close .menu': 'closeMenu', 'close .menu': 'closeMenu',
'select .message-list .entry': 'messageDetail', 'select .message-list .entry': 'messageDetail',
'force-resize': 'forceUpdateMessageFieldSize', 'force-resize': 'forceUpdateMessageFieldSize',
'show-identity': 'showIdentity' 'show-identity': 'showSafetyNumber'
}, },
markAllAsVerifiedDefault: function(unverified) { markAllAsVerifiedDefault: function(unverified) {
return Promise.all(unverified.map(function(contact) { return Promise.all(unverified.map(function(contact) {
return contact.setVerifiedDefault(); if (contact.isUnverified()) {
})); return contact.setVerifiedDefault();
}
}.bind(this)));
}, },
openSafetyNumberScreens: function(unverified) { openSafetyNumberScreens: function(unverified) {

@ -62,6 +62,8 @@
view = new Whisper.ExpirationTimerUpdateView({model: model}).render(); view = new Whisper.ExpirationTimerUpdateView({model: model}).render();
} else if (model.get('type') === 'keychange') { } else if (model.get('type') === 'keychange') {
view = new Whisper.KeyChangeView({model: model}).render(); view = new Whisper.KeyChangeView({model: model}).render();
} else if (model.get('type') === 'verified-change') {
view = new Whisper.VerifiedChangeView({model: model}).render();
} else { } else {
view = new this.itemView({model: model}).render(); view = new this.itemView({model: model}).render();
this.listenTo(view, 'beforeChangeHeight', this.measureScrollPosition); this.listenTo(view, 'beforeChangeHeight', this.measureScrollPosition);

@ -98,6 +98,37 @@
} }
}); });
Whisper.VerifiedChangeView = Whisper.View.extend({
tagName: 'li',
className: 'verified-change',
templateName: 'verified-change',
id: function() {
return this.model.id;
},
initialize: function() {
this.conversation = this.model.getModelForVerifiedChange();
},
events: {
'click .content': 'showIdentity'
},
render_attributes: function() {
if (this.model.get('verified')) {
return {
icon: 'verified',
content: i18n('youMarkedAsVerified', this.conversation.getTitle())
};
}
return {
icon: 'shield',
content: i18n('youMarkedAsNotVerified', this.conversation.getTitle())
};
},
showIdentity: function() {
this.$el.trigger('show-identity', this.conversation);
}
});
Whisper.MessageView = Whisper.View.extend({ Whisper.MessageView = Whisper.View.extend({
tagName: 'li', tagName: 'li',
templateName: 'message', templateName: 'message',

@ -674,6 +674,32 @@ li.entry .error-icon-container {
} }
} }
.message-list li.verified-change {
text-align: center;
.icon {
height: 1.25em;
width: 1.25em;
vertical-align: text-bottom;
display: inline-block;
&.verified {
@include color-svg('/images/verified-check.svg', $grey_d);
}
&.shield {
@include color-svg('/images/shield.svg', $grey_d);
}
}
.content {
cursor: pointer;
display: inline-block;
padding: 5px 10px;
background: #fff5c4;
color: $grey_d;
border-radius: $border-radius;
}
}
.message-list .last-seen-indicator-view { .message-list .last-seen-indicator-view {
// This padding is large so we clear the avatar circle extending into the conversation // This padding is large so we clear the avatar circle extending into the conversation
// window.scrollIntoView() doesn't honor margins, so we're using padding // window.scrollIntoView() doesn't honor margins, so we're using padding

@ -1540,6 +1540,29 @@ li.entry .error-icon-container {
color: #454545; color: #454545;
border-radius: 5px; } border-radius: 5px; }
.message-list li.verified-change {
text-align: center; }
.message-list li.verified-change .icon {
height: 1.25em;
width: 1.25em;
vertical-align: text-bottom;
display: inline-block; }
.message-list li.verified-change .icon.verified {
-webkit-mask: url("/images/verified-check.svg") no-repeat center;
-webkit-mask-size: 100%;
background-color: #454545; }
.message-list li.verified-change .icon.shield {
-webkit-mask: url("/images/shield.svg") no-repeat center;
-webkit-mask-size: 100%;
background-color: #454545; }
.message-list li.verified-change .content {
cursor: pointer;
display: inline-block;
padding: 5px 10px;
background: #fff5c4;
color: #454545;
border-radius: 5px; }
.message-list .last-seen-indicator-view { .message-list .last-seen-indicator-view {
padding-top: 25px; padding-top: 25px;
padding-bottom: 35px; } padding-bottom: 35px; }

@ -185,6 +185,12 @@
{{ messageNotSent }} {{ messageNotSent }}
<span href='#' class='retry'>{{ resend }}</span> <span href='#' class='retry'>{{ resend }}</span>
</script> </script>
<script type='text/x-tmpl-mustache' id='keychange'>
<span class='content' dir='auto'>{{ content }}</span>
</script>
<script type='text/x-tmpl-mustache' id='verified-change'>
<span class='content' dir='auto'><span class='{{ icon }} icon'></span> {{ content }}</span>
</script>
<script type='text/x-tmpl-mustache' id='message'> <script type='text/x-tmpl-mustache' id='message'>
{{> avatar }} {{> avatar }}
<div class='bubble {{ avatar.color }}'> <div class='bubble {{ avatar.color }}'>

Loading…
Cancel
Save