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": {
|
"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 }}'>
|
||||||
|
|
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() {
|
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…
Add table
Add a link
Reference in a new issue