Add items to conversation history when user verifies/unverifies

FREEBIE
pull/749/head
Scott Nonnenberg 7 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": {
"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"

@ -193,6 +193,9 @@
<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'>
{{> avatar }}
<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() {
return conversations.fetchActive();
}

@ -98,6 +98,9 @@
// return textsecure.storage.protocol.setVerified(this.id, DEFAULT).then(function() {
return updateTrustStore(this.id, DEFAULT).then(function() {
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));
},
setVerified: function() {
@ -114,6 +117,9 @@
// return textsecure.storage.protocol.setVerified(this.id, VERIFIED).then(function() {
return updateTrustStore(this.id, VERIFIED).then(function() {
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));
},
isVerified: function() {
@ -235,7 +241,7 @@
},
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 message = new Whisper.Message({
conversationId : this.id,
@ -246,6 +252,27 @@
});
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) {
if (this.messageCollection.get(message.id)) {
@ -382,6 +409,9 @@
var collection = new Whisper.MessageCollection();
return collection.fetchConversation(this.id, 1).then(function() {
var lastMessage = collection.at(0);
if (lastMessage.get('type') === 'verified-change') {
return;
}
if (lastMessage) {
this.set({
lastMessage : lastMessage.getNotificationText(),
@ -551,6 +581,9 @@
return this.messageCollection.fetchConversation(this.id, null, this.get('unreadCount'));
},
hasMember: function(number) {
return _.contains(this.get('members'), number);
},
fetchContacts: function(options) {
return new Promise(function(resolve) {
if (this.isPrivate()) {

@ -182,6 +182,18 @@
}
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() {
return this.get('type') === 'outgoing';
},

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

@ -62,6 +62,8 @@
view = new Whisper.ExpirationTimerUpdateView({model: model}).render();
} else if (model.get('type') === 'keychange') {
view = new Whisper.KeyChangeView({model: model}).render();
} else if (model.get('type') === 'verified-change') {
view = new Whisper.VerifiedChangeView({model: model}).render();
} else {
view = new this.itemView({model: model}).render();
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({
tagName: 'li',
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 {
// 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

@ -1540,6 +1540,29 @@ li.entry .error-icon-container {
color: #454545;
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 {
padding-top: 25px;
padding-bottom: 35px; }

@ -185,6 +185,12 @@
{{ messageNotSent }}
<span href='#' class='retry'>{{ resend }}</span>
</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'>
{{> avatar }}
<div class='bubble {{ avatar.color }}'>

Loading…
Cancel
Save