Add items to conversation history when user verifies/unverifies
FREEBIE
This commit is contained in:
parent
02973372aa
commit
1cf9289b1a
12 changed files with 168 additions and 4 deletions
|
@ -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 }}'>
|
||||
|
|
1
images/shield.svg
Normal file
1
images/shield.svg
Normal file
|
@ -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…
Reference in a new issue