Improve group update ui/ux

Promote group update to its own screen. Add typeahead contact selector
from new conversation view. Restyle to match android (more or less).

Closes #186
This commit is contained in:
lilia 2015-03-12 11:40:55 -07:00
parent 7e3961891b
commit 69d5a6a33c
10 changed files with 383 additions and 231 deletions

View file

@ -34,7 +34,7 @@
<div class="bottom-bar" id='footer'>
<form class='send'>
<div class='attachments'>
<div class='paperclip'></div>
<div class='paperclip thumbnail'></div>
<input type='file' class='file-input'>
</div>
<input class="send-btn" type='submit' value='' />
@ -59,14 +59,54 @@
</div>
</script>
<script type='text/x-tmpl-mustache' id='new-group-update-form'>
<div>
<input type='text' name='name' class='name' placeholder='Group Name' value="{{ name }}">
<div class='title-bar' id='header'>
<button class='back'></button>
<button class='send check'></button>
<span class='title-text'>Update group</span>
</div>
<div class='group-avatar'>
<div><input type='file' name='avatar' class='file-input'></div>
<div class='container'>
<div class='scrollable'>
<div class='clearfix'>
<div class='group-avatar'>
<div class='thumbnail'>
<span class='default'></span>
</div>
<input type='file' name='avatar' class='file-input'>
</div>
<div>
<input type='text' name='name' class='name' placeholder='Group Name' value="{{ name }}">
</div>
</div>
</div>
</div>
</script>
<script type='text/x-tmpl-mustache' id='contact_pill'>
<span>{{ name }}</span><span class='remove'>x</span>
</script>
<script type='text/x-tmpl-mustache' id='recipients-input'>
<div class='recipients-container'>
<span class='recipients'></span>
<input type='text' class='search' placeholder="Add member" />
</div>
<div class='results'>
<div class='new-contact contact'></div>
<div class='contacts'></div>
</div>
</script>
<script type='text/x-tmpl-mustache' id='contact'>
<span class='avatar'></span>
<div class='contact-details'>
<h3 class='contact-name'>
{{ contact_name }}
</h3>
<p class='number'>{{ number }}</p>
<p class='last-message'>
{{ last_message }}
</p>
<span class='last-timestamp'>
{{ last_message_timestamp }}
</span>
</div>
<div>Add members: <input name='members' class='members'></div>
<button class='send'>Update</button>
</script>
<script type="text/x-tmpl-mustache" id="phone-number">
<div class="phone-input-form">
@ -142,6 +182,9 @@
<script type="text/javascript" src="js/views/attachment_preview_view.js"></script>
<script type="text/javascript" src="js/views/file_input_view.js"></script>
<script type="text/javascript" src="js/views/list_view.js"></script>
<script type="text/javascript" src="js/views/conversation_list_item_view.js"></script>
<script type="text/javascript" src="js/views/conversation_list_view.js"></script>
<script type="text/javascript" src="js/views/recipients_input_view.js"></script>
<script type="text/javascript" src="js/views/new_group_update_view.js"></script>
<script type="text/javascript" src="js/views/end_session_view.js"></script>
<script type="text/javascript" src="js/views/group_update_view.js"></script>

BIN
images/group_default.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 B

View file

@ -57,7 +57,9 @@
<div class='scrollable'>
<div class='new-group-update-form clearfix'>
<div class='group-avatar'>
<div class='paperclip'></div>
<div class='thumbnail'>
<span class='default group-default'></span>
</div>
<input type='file' name='avatar' class='file-input'>
</div>
<input type='text' name='name' class='name' placeholder='Group Name' value="{{ name }}">

View file

@ -97,6 +97,10 @@
view.$el.insertAfter(this.$el);
this.$el.hide();
view.render();
this.listenBack(view);
},
listenBack: function(view) {
this.listenTo(view, 'back', function() {
view.remove();
this.$el.show();
@ -124,14 +128,12 @@
},
newGroupUpdate: function() {
if (!this.newGroupUpdateView) {
this.newGroupUpdateView = new Whisper.NewGroupUpdateView({
model: this.model
});
} else {
this.newGroupUpdateView.delegateEvents();
}
this.newGroupUpdateView.render().$el.insertBefore(this.view.el);
this.newGroupUpdateView = new Whisper.NewGroupUpdateView({
model: this.model
});
this.newGroupUpdateView.$el.insertAfter(this.el);
this.$el.hide();
this.listenBack(this.newGroupUpdateView);
},
destroyMessages: function(e) {

View file

@ -28,12 +28,13 @@
this.$input = this.$el.find('input[type=file]');
this.thumb = new Whisper.AttachmentPreviewView();
this.$el.addClass('file-input');
this.$default = this.$el.find('.default');
},
events: {
'change': 'previewImages',
'click .close': 'deleteFiles',
'click .paperclip': 'open'
'click .thumbnail': 'open'
},
open: function() {
@ -41,8 +42,9 @@
},
addThumb: function(src) {
this.$default.hide();
this.thumb.src = src;
this.$el.find('.paperclip').append(this.thumb.render().el);
this.$el.find('.thumbnail').append(this.thumb.render().el);
},
autoScale: function(file) {
@ -163,6 +165,7 @@
this.oUrl = null;
}
this.thumb.remove();
this.$default.show();
},
deleteFiles: function(e) {

View file

@ -28,21 +28,33 @@
});
if (this.model.attributes.avatar) {
new Whisper.AttachmentView({
this.current_avatar = new Whisper.AttachmentView({
model: this.model.attributes.avatar
}).render().$el.addClass('preview').prependTo(this.avatarInput.el);
});
this.avatarInput.$default.append(
this.current_avatar.render().$el
);
}
this.recipients_view = new Whisper.RecipientsInputView();
this.$el.find('.scrollable').append(this.recipients_view.el);
},
events: {
'click .back': 'goBack',
'click .send': 'send'
},
goBack: function() {
this.trigger('back');
},
render_attributes: function() {
return { name: this.model.getTitle() };
},
send: function() {
return this.avatarInput.getFiles().then(function(avatarFiles) {
this.model.save({
name: this.$el.find('.name').val(),
avatar: avatarFiles[0],
members: _.union(this.model.get('members'), this.$el.find('.members').val().split(','))
members: _.union(this.model.get('members'), this.recipients_view.recipients.pluck('id'))
});
textsecure.messaging.updateGroup(
this.model.id,
@ -50,7 +62,7 @@
this.model.get('avatar'),
this.model.get('members')
);
this.remove();
this.goBack();
}.bind(this));
}
});

View file

@ -1,7 +1,12 @@
.conversation {
padding: $header-height 0;
.file-input .close {
top: -10px;
}
}
.conversation + .new-group-update-form,
.conversation, .discussion-container, .message-list, .message-detail, .key-verification {
height: 100%;
}
@ -48,6 +53,16 @@
font-size: smaller;
}
.new-group-update-form {
.container {
height: 100%;
padding-top: $header-height;
}
.scrollable {
padding: 0.5em;
}
}
.private .sender,
.outgoing .sender {
display: none;
@ -278,12 +293,3 @@
font-size: small;
}
.attachment-preview {
background: white;
width: 100%;
height: 100%;
img {
width: 100%;
}
}

View file

@ -108,12 +108,16 @@ button.back {
.file-input {
position: relative;
width: 36px;
margin-right: 10px;
cursor: pointer;
.thumbnail {
width: 36px;
height: 36px;
}
.paperclip {
width: 100%;
height: 100%;
width: 36px;
height: 36px;
background: url('/images/paperclip.png') no-repeat;
background-size: 90%;
background-position: center 6px;
@ -131,17 +135,12 @@ button.back {
z-index: 1;
}
img.preview {
max-width: 100%;
}
.close {
font-family: sans-serif;
color: white;
position: absolute;
top: -10px;
left: 20px;
text-align: center;
top: 0;
right: -8px;
cursor: default;
border-radius: 50%;
width: 20px;
@ -162,18 +161,157 @@ img.emoji {
}
.new-group-update-form {
background: white;
.group-avatar {
float: left;
height: 36px;
}
.group-default {
position: relative;
display: inline-block;
width: 100%;
height: 100%;
border-radius: 50%;
background: $grey_l url('/images/group_default.png') no-repeat center;
}
.file-input .thumbnail,
img {
height: 54px;
width: 54px;
border-radius: (54px / 2);
}
.thumbnail:after {
content: '';
position: absolute;
height: 0;
width: 0;
bottom: 0;
right: 0;
border-bottom: 10px solid $grey;
border-left: 10px solid transparent;
}
input.name {
padding: 0.5em;
border: solid 1px #ccc;
border-width: 0 0 1px 0;
width: calc(100% - 64px);
}
}
.title-bar .check {
float: right;
background: $blue url('/images/check.png') no-repeat center center;
margin: none;
}
.contact {
position: relative;
padding: 12px;
background: white;
cursor: pointer;
transition: background 0.2s;
white-space: nowrap;
overflow: hidden;
&::after {
content: '';
position: absolute;
right: 16px;
bottom: 0;
height: 1px;
width: calc(100% - 12px - 54px - 2 * 8px - 16px);
background: #eee;
}
&:hover {
background-color: $blue_l;
background: #f8f8f8;
}
&:last-child {
box-shadow: 0 1px 3px rgba(#aaa, 0.8);
&::after {
display: none;
}
}
.avatar img {
height: 44px;
width: 44px;
background: $grey_l;
border-radius: (44px / 2);
}
.contact-details {
vertical-align: top;
display: inline-block;
margin: 4px 0 0 8px;
}
.contact-name {
margin: 0;
font-size: 1em;
font-weight: 400;
}
}
.recipients-input {
.recipients-container {
background-color: white;
padding: 2px;
border-bottom: 1px solid #f2f2f2;
line-height: 24px;
}
.recipient {
display: inline-block;
margin: 0 2px 2px 0;
padding: 0 5px;
border-radius: 10px;
background-color: $blue;
color: white;
&.error {
background-color: #f00;
}
.remove {
margin-left: 5px;
padding: 0 2px;
}
}
.contact {
.number {
display: inline-block;
}
.last-message, .last-timestamp {
display: none;
}
.number {
color: $grey;
font-size: small;
}
}
}
.attachment-preview {
width: 100%;
height: 100%;
background: white;
img {
width: 100%;
}
}

View file

@ -52,37 +52,6 @@ input.search {
outline: 0;
}
.new-conversation {
.new-group-update-form {
display: none;
}
.recipients-container {
background-color: white;
padding: 2px;
border-bottom: 1px solid #f2f2f2;
line-height: 24px;
}
.recipient {
display: inline-block;
margin: 0 2px 2px 0;
padding: 0 5px;
border-radius: 10px;
background-color: $blue;
color: white;
&.error {
background-color: #f00;
}
.remove {
margin-left: 5px;
padding: 0 2px;
}
}
}
.fab {
z-index: 1;
position: fixed;
@ -111,23 +80,10 @@ input.search {
}
.new-conversation {
.last-message, .last-timestamp {
display: none;
}
.contact {
.checkbox, .number {
display: inline-block;
}
.number {
color: $grey;
font-size: small;
}
}
}
.new-contact {
display: none;
.contact-name { display: none; }
.contact-details::before {
content: 'Create new contact';
@ -142,48 +98,9 @@ input.search {
color: $grey_d;
background: #eee;
.contact {
position: relative;
padding: 12px;
background: white;
cursor: pointer;
transition: background 0.2s;
white-space: nowrap;
overflow: hidden;
&::after {
content: '';
position: absolute;
right: 16px;
bottom: 0;
height: 1px;
width: calc(100% - 12px - 54px - 2 * 8px - 16px);
background: #eee;
}
&:hover {
background: #f8f8f8;
}
&:last-child {
box-shadow: 0 1px 3px rgba(#aaa, 0.8);
&::after {
display: none;
}
}
}
.contact-details {
vertical-align: top;
display: inline-block;
margin: 4px 0 0 8px;
}
.contact-name {
margin: 0;
font-size: 1em;
font-weight: 400;
.new-group-update-form {
display: none;
padding: 0.5em;
}
.last-message {
@ -199,13 +116,6 @@ input.search {
color: #888;
}
.avatar img {
height: 44px;
width: 44px;
background: $grey_l;
border-radius: (44px / 2);
}
}
.settings {

View file

@ -101,11 +101,14 @@ button.back {
.file-input {
position: relative;
width: 36px;
margin-right: 10px; }
margin-right: 10px;
cursor: pointer; }
.file-input .thumbnail {
width: 36px;
height: 36px; }
.file-input .paperclip {
width: 100%;
height: 100%;
width: 36px;
height: 36px;
background: url("/images/paperclip.png") no-repeat;
background-size: 90%;
background-position: center 6px; }
@ -119,15 +122,12 @@ button.back {
left: 0;
cursor: pointer;
z-index: 1; }
.file-input img.preview {
max-width: 100%; }
.file-input .close {
font-family: sans-serif;
color: white;
position: absolute;
top: -10px;
left: 20px;
text-align: center;
top: 0;
right: -8px;
cursor: default;
border-radius: 50%;
width: 20px;
@ -143,16 +143,108 @@ img.emoji {
margin: 0 .05em 0 .1em;
vertical-align: -0.1em; }
.new-group-update-form .group-avatar {
float: left;
height: 36px; }
.new-group-update-form {
background: white; }
.new-group-update-form .group-avatar {
float: left; }
.new-group-update-form .group-default {
position: relative;
display: inline-block;
width: 100%;
height: 100%;
border-radius: 50%;
background: #f3f3f3 url("/images/group_default.png") no-repeat center; }
.new-group-update-form .file-input .thumbnail,
.new-group-update-form img {
height: 54px;
width: 54px;
border-radius: 27px; }
.new-group-update-form .thumbnail:after {
content: '';
position: absolute;
height: 0;
width: 0;
bottom: 0;
right: 0;
border-bottom: 10px solid #616161;
border-left: 10px solid transparent; }
.new-group-update-form input.name {
padding: 0.5em;
border: solid 1px #ccc;
border-width: 0 0 1px 0;
width: calc(100% - 64px); }
.title-bar .check {
float: right;
background: #2a92e7 url("/images/check.png") no-repeat center center;
margin: none; }
.title-bar .check:hover {
background-color: #a2d2f4; }
background: #2a92e7 url("/images/check.png") no-repeat center center; }
.contact {
position: relative;
padding: 12px;
background: white;
cursor: pointer;
transition: background 0.2s;
white-space: nowrap;
overflow: hidden; }
.contact::after {
content: '';
position: absolute;
right: 16px;
bottom: 0;
height: 1px;
width: calc(100% - 12px - 54px - 2 * 8px - 16px);
background: #eee; }
.contact:hover {
background: #f8f8f8; }
.contact:last-child {
box-shadow: 0 1px 3px rgba(170, 170, 170, 0.8); }
.contact:last-child::after {
display: none; }
.contact .avatar img {
height: 44px;
width: 44px;
background: #f3f3f3;
border-radius: 22px; }
.contact .contact-details {
vertical-align: top;
display: inline-block;
margin: 4px 0 0 8px; }
.contact .contact-name {
margin: 0;
font-size: 1em;
font-weight: 400; }
.recipients-input .recipients-container {
background-color: white;
padding: 2px;
border-bottom: 1px solid #f2f2f2;
line-height: 24px; }
.recipients-input .recipient {
display: inline-block;
margin: 0 2px 2px 0;
padding: 0 5px;
border-radius: 10px;
background-color: #2a92e7;
color: white; }
.recipients-input .recipient.error {
background-color: #f00; }
.recipients-input .recipient .remove {
margin-left: 5px;
padding: 0 2px; }
.recipients-input .contact .number {
display: inline-block; }
.recipients-input .contact .last-message, .recipients-input .contact .last-timestamp {
display: none; }
.recipients-input .contact .number {
color: #616161;
font-size: small; }
.attachment-preview {
width: 100%;
height: 100%;
background: white; }
.attachment-preview img {
width: 100%; }
.gutter {
padding: 36px 0 0; }
@ -190,26 +282,6 @@ input.search {
margin: 0;
outline: 0; }
.new-conversation .new-group-update-form {
display: none; }
.new-conversation .recipients-container {
background-color: white;
padding: 2px;
border-bottom: 1px solid #f2f2f2;
line-height: 24px; }
.new-conversation .recipient {
display: inline-block;
margin: 0 2px 2px 0;
padding: 0 5px;
border-radius: 10px;
background-color: #2a92e7;
color: white; }
.new-conversation .recipient.error {
background-color: #f00; }
.new-conversation .recipient .remove {
margin-left: 5px;
padding: 0 2px; }
.fab {
z-index: 1;
position: fixed;
@ -233,56 +305,23 @@ input.search {
.last-timestamp {
font-size: smaller; }
.new-conversation .last-message, .new-conversation .last-timestamp {
.new-contact {
display: none; }
.new-conversation .contact .checkbox, .new-conversation .contact .number {
display: inline-block; }
.new-conversation .contact .number {
color: #616161;
font-size: small; }
.new-contact .contact-name {
display: none; }
.new-contact .contact-details::before {
content: 'Create new contact';
display: block;
font-style: italic;
opacity: 0.7;
padding-right: 8px; }
.new-contact .contact-name {
display: none; }
.new-contact .contact-details::before {
content: 'Create new contact';
display: block;
font-style: italic;
opacity: 0.7;
padding-right: 8px; }
.index {
color: #454545;
background: #eee; }
.index .contact {
position: relative;
padding: 12px;
background: white;
cursor: pointer;
transition: background 0.2s;
white-space: nowrap;
overflow: hidden; }
.index .contact::after {
content: '';
position: absolute;
right: 16px;
bottom: 0;
height: 1px;
width: calc(100% - 12px - 54px - 2 * 8px - 16px);
background: #eee; }
.index .contact:hover {
background: #f8f8f8; }
.index .contact:last-child {
box-shadow: 0 1px 3px rgba(170, 170, 170, 0.8); }
.index .contact:last-child::after {
display: none; }
.index .contact-details {
vertical-align: top;
display: inline-block;
margin: 4px 0 0 8px; }
.index .contact-name {
margin: 0;
font-size: 1em;
font-weight: 400; }
.index .new-group-update-form {
display: none;
padding: 0.5em; }
.index .last-message {
margin: 6px 0;
font-size: small;
@ -292,11 +331,6 @@ input.search {
top: 14px;
right: 12px;
color: #888; }
.index .avatar img {
height: 44px;
width: 44px;
background: #f3f3f3;
border-radius: 22px; }
.settings {
height: 100%;
@ -313,7 +347,10 @@ input.search {
.conversation {
padding: 36px 0; }
.conversation .file-input .close {
top: -10px; }
.conversation + .new-group-update-form,
.conversation, .discussion-container, .message-list, .message-detail, .key-verification {
height: 100%; }
@ -346,6 +383,12 @@ input.search {
.group-update {
font-size: smaller; }
.new-group-update-form .container {
height: 100%;
padding-top: 36px; }
.new-group-update-form .scrollable {
padding: 0.5em; }
.private .sender,
.outgoing .sender {
display: none; }
@ -525,10 +568,3 @@ input.search {
box-shadow: 0 0 5px 0 black;
border-radius: 20px;
font-size: small; }
.attachment-preview {
background: white;
width: 100%;
height: 100%; }
.attachment-preview img {
width: 100%; }