浏览代码

Start on panels

Riley Shaw 9 年之前
父节点
当前提交
2cbcb28ee3

+ 74 - 0
conversation.html

@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<html class='no-js' lang='en'>
+    <head>
+        <meta charset='utf-8'>
+        <meta content='width=device-width, user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0' name='viewport'>
+        <meta http-equiv="X-UA-Compatible" content="IE=edge">
+        <title></title>
+        <meta name="description" content="">
+        <meta name="viewport" content="width=device-width, initial-scale=1">
+        <link href='/favicon.ico' rel='shortcut icon'>
+        <link href="/stylesheets/normalize.css" rel="stylesheet" type="text/css" />
+        <link href="/stylesheets/manifest.css" rel="stylesheet" type="text/css" />
+        <link href="/components/bootstrap-tagsinput/dist/bootstrap-tagsinput.css" rel="stylesheet" type="text/css" />
+        <link href="/stylesheets/index.css" rel="stylesheet" type="text/css" />
+    </head>
+    <body class='signal index' data-name="curve25519" data-tools="pnacl" data-configs="Debug Release" data-path="nacl/pnacl/{config}">
+        <div class='title-bar' id='header'>Settings and whatever</div>
+        <ul id='conversation-container'>
+
+        </ul>
+
+        <div class="bottom-bar">
+            <button>Attachments</button>
+            <form class='send'>
+                <input class='send-message' rows='6' type='textarea'>
+                <div class='attachments'>
+                    <input type='file' name='files[]' multiple class='file-input'>
+                </div>
+            </form>
+            <button>Send</button>
+        </div>
+
+        <script type='text/x-tmpl-mustache' id='message'>
+            <li>
+                <img class="avatar" src="#" alt="">
+                <div class="bubble {{ bubble_class }}">
+                    <p class="content">{{ message }}</p>
+                    <p class="sender">{{ sender }}</p>
+                    <p class="timestamp">{{ timestamp }}</p>
+                </div>
+            </li>
+        </script>
+
+        <script type="text/javascript" src="js/components.js"></script>
+
+        <script type="text/javascript" src="js/libtextsecure.js"></script>
+        <script type="text/javascript" src="js/database.js"></script>
+
+        <script type="text/javascript" src="components/bootstrap-tagsinput/dist/bootstrap-tagsinput.js"></script>
+
+        <script type="text/javascript" src="js/libphonenumber-util.js"></script>
+
+        <script type="text/javascript" src="js/models/messages.js"></script>
+        <script type="text/javascript" src="js/models/conversations.js"></script>
+
+        <script type="text/javascript" src="js/chromium.js"></script>
+
+        <script type="text/javascript" src="js/views/file_modal_view.js"></script>
+        <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/group_update_view.js"></script>
+        <script type="text/javascript" src="js/views/attachment_view.js"></script>
+        <script type="text/javascript" src="js/views/message_view.js"></script>
+        <script type="text/javascript" src="js/views/message_list_view.js"></script>
+
+        <script type="text/javascript" src="js/views/conversation_view.js"></script>
+
+        <script type="text/javascript" src="js/conversation_panel.js"></script>
+
+        <div id="listener"></div>
+        <div id="log"></div>
+    </body>
+</html>

+ 77 - 0
index2.html

@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html class='no-js' lang='en'>
+    <head>
+        <meta charset='utf-8'>
+        <meta content='width=device-width, user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0' name='viewport'>
+        <meta http-equiv="X-UA-Compatible" content="IE=edge">
+        <title>
+        Signal for Chrome
+        </title>
+        <meta name="description" content="">
+        <meta name="viewport" content="width=device-width, initial-scale=1">
+        <link href='/favicon.ico' rel='shortcut icon'>
+        <link href="/stylesheets/normalize.css" rel="stylesheet" type="text/css" />
+        <link href="/stylesheets/manifest.css" rel="stylesheet" type="text/css" />
+        <link href="/components/bootstrap-tagsinput/dist/bootstrap-tagsinput.css" rel="stylesheet" type="text/css" />
+        <link href="/stylesheets/index.css" rel="stylesheet" type="text/css" />
+    </head>
+    <body class='signal index' data-name="curve25519" data-tools="pnacl" data-configs="Debug Release" data-path="nacl/pnacl/{config}">
+        <div class='title-bar' id='header'>
+            <a href id='new-message'>New message</a>
+            <a href id='new-group'>New group</a>
+        </div>
+        <div id='gutter' class='gutter'>
+            <div class='search'>
+                <form>
+                  <input name='contact_search' placeholder='Search' type='search'>
+                </form>
+            </div>
+            <div id='contacts'></div>
+        </div>
+
+        <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='last-message'>
+                {{ last_message }}
+                </p>
+                <span class='last-timestamp'>
+                {{ last_message_timestamp }}
+                </span>
+            </div>
+        </script>
+
+        <script type="text/javascript" src="js/components.js"></script>
+
+        <script type="text/javascript" src="js/libtextsecure.js"></script>
+        <script type="text/javascript" src="js/database.js"></script>
+
+        <script type="text/javascript" src="components/bootstrap-tagsinput/dist/bootstrap-tagsinput.js"></script>
+
+        <script type="text/javascript" src="js/libphonenumber-util.js"></script>
+
+        <script type="text/javascript" src="js/models/messages.js"></script>
+        <script type="text/javascript" src="js/models/conversations.js"></script>
+
+        <script type="text/javascript" src="js/chromium.js"></script>
+        <script type="text/javascript" src="js/views/notifications.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/group_update_view.js"></script>
+        <script type="text/javascript" src="js/views/attachment_view.js"></script>
+        <script type="text/javascript" src="js/views/message_view.js"></script>
+        <script type="text/javascript" src="js/views/message_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/conversation_view.js"></script>
+        <script type="text/javascript" src="js/views/new_conversation_view.js"></script>
+        <script type="text/javascript" src="js/views/new_group_view.js"></script>
+        <script type="text/javascript" src="js/views/inbox_view.js"></script>
+        <script type="text/javascript" src="js/index.js"></script>
+        <div id="listener"></div>
+        <div id="log"></div>
+    </body>
+</html>

+ 26 - 1
js/background.js

@@ -56,6 +56,32 @@
                 request.respond(500, 'Bad encrypted websocket message');
             });
         });
+        var opened = false;
+        var panel = 0;
+
+        chrome.browserAction.onClicked.addListener(function () {
+            if (opened === false) {
+                opened = true;
+                chrome.windows.create({
+                    url: 'index2.html',
+                    type: 'panel',
+                    focused: true,
+                    width: 260, // 280 for chat
+                    height: 440 // 420 for chat
+                }, function (window) {
+                    var isPanelEnabled = window.alwaysOnTop;
+                    panel = window.id;
+                });
+            } else if (opened === true) {
+                chrome.windows.update(panel, { focused: true });
+            }
+            chrome.windows.onRemoved.addListener(function (windowId) {
+                if (windowId === panel) {
+                    panel = 0;
+                    opened = false;
+                }
+            });
+        });
     };
 
     function onMessageReceived(pushMessage) {
@@ -196,5 +222,4 @@
             console.log('got delivery receipt for unknown message', pushMessage.source, timestamp);
         });
     };
-
 })();

+ 57 - 0
js/conversation_panel.js

@@ -0,0 +1,57 @@
+/*global $, Whisper, Backbone, textsecure, extension*/
+/* vim: ts=4:sw=4:expandtab:
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+(function () {
+  'use strict';
+
+    window.Whisper = window.Whisper || {};
+
+    function loadConversation (id) {
+        var conversation = new Whisper.Conversation({ id: id });
+        conversation.fetch().then(function () {
+            new Whisper.ConversationView({ model: conversation}).render().$el.appendTo($('#conversation-container'));
+        });
+
+        // clean 'er up
+        conversationInfo = undefined;
+    };
+
+    var conversationInfo = {
+        id: '',
+        idPairs: {}
+    };
+
+    extension.on('loadConversation', function (message) {
+        debugger;
+        if (conversationInfo.id) {
+            if (message.windowId === conversationInfo.id) {
+                loadConversation(message.conversationId);
+            }
+        } else {
+            conversationInfo.idPairs[message.windowId] = message.conversationId;
+        }
+    });
+
+    chrome.windows.getCurrent(function (windowInfo) {
+        window.document.title = conversationInfo.id = windowInfo.id;
+
+        var conversationId = conversationInfo.idPairs[conversationInfo.id];
+
+        if (typeof conversationId !== 'undefined') {
+            loadConversation(conversationId);
+        }
+    });
+}());

+ 18 - 0
js/views/conversation_list_item_view.js

@@ -19,6 +19,7 @@ var Whisper = Whisper || {};
 (function () {
   'use strict';
 
+  // list of conversations, showing user/group and last message sent
   Whisper.ConversationListItemView = Backbone.View.extend({
     tagName: 'div',
     className: 'contact',
@@ -36,11 +37,28 @@ var Whisper = Whisper || {};
     },
 
     open: function(e) {
+      var modelId = this.model.id;
+
       this.$el.addClass('selected');
 
       if (!this.view) {
         this.view = new Whisper.ConversationView({ model: this.model });
       }
+
+      chrome.windows.create({
+        url: 'conversation.html#' + modelId,
+        type: 'panel',
+        focused: true,
+        width: 280,
+        height: 420
+      }, function (windowInfo) {
+	debugger;
+        extension.trigger('loadConversation', {
+          windowId: windowInfo.id,
+          conversationId: modelId
+        });
+      });
+
       this.model.collection.trigger('selected', this.view);
     },
 

+ 15 - 2
js/views/conversation_view.js

@@ -37,8 +37,8 @@
             this.view = new Whisper.MessageListView({
                 collection: this.model.messageCollection
             });
-            this.$el.find('.discussion-container').append(this.view.el);
-
+            $('#conversation-container').append(this.view.el);
+//new ...({el: $(#conversation-container)})
             this.model.fetchMessages({reset: true});
         },
 
@@ -83,7 +83,20 @@
             }
         },
 
+        /*addAll: function() {
+            this.collection.each(this.addOne);
+        },
+        addOne: function(model) {
+            var view = new Whisper.Message({model: model});
+            view.render();
+            $(this.el).append(view.el);
+            model.bind('remove', view.remove);
+        },*/
+
         render: function() {
+            //this.$el.empty();
+            //this.addAll();
+
             this.delegateEvents();
             this.view.delegateEvents();
             this.view.scrollToBottom();

+ 0 - 17
js/views/inbox_view.js

@@ -22,9 +22,7 @@
         initialize: function () {
             this.gutter = $('#gutter');
             this.contacts = $('#contacts');
-            this.resize();
 
-            window.addEventListener('resize', this.resize.bind(this));
             this.conversations = new Whisper.ConversationCollection();
 
             new Whisper.ConversationListView({
@@ -70,23 +68,8 @@
             });
             this.setContent(view.render().$el.show());
         },
-        resize: function (e) {
-            var windowheight = window.innerHeight,
-                form = $('.send-message-area').outerHeight(),
-                gutter_offset = this.gutter.offset().top,
-                contacts_offset = this.contacts.offset().top;
-            if (window.innerWidth < 480) {
-                this.gutter.css('height', windowheight - gutter_offset - form);
-                this.contacts.css('height', windowheight - contacts_offset - form);
-            } else {
-                this.gutter.css('height', windowheight - gutter_offset);
-                this.contacts.css('height', windowheight - contacts_offset);
-            }
-            $('.discussion').css('height', windowheight - gutter_offset - form);
-        },
         setContent: function (content) {
             $(content).insertAfter(this.gutter);
-            this.resize();
         }
     });
 

+ 1 - 1
manifest.json

@@ -16,7 +16,7 @@
         "default_icon": {
             "19": "icon.png"
         },
-        "default_popup": "index.html"
+        "default_title": "TextSecure"
     },
 
     "background": {

+ 0 - 73
stylesheets/_gutter.scss

@@ -1,73 +0,0 @@
-
-.gutter {
-  float:left;
-  border-right:1px solid lightgray;
-  width:240px;
-  position:relative;
-  background-color:blue;
-  z-index:100;
-  .contact {
-    float:left;
-    width:100%;
-    border-bottom:1px solid whitesmoke;
-    color:#333;
-    &:hover {
-      background-color:whitesmoke;
-      margin-top:-1px;
-      border-bottom:1px solid lightgray;
-      border-top:1px solid lightgray;
-    }
-  }
-  .contact-details {
-    position:relative;
-    width:156px;
-    float:left;
-    text-align: left;
-    h3 {
-      font-size:13px;
-      margin-bottom:4px;
-    }
-    .last-message {
-      color:lighten(#333, 40%);
-      letter-spacing:0.15px;
-      -webkit-text-stroke: 0.2px;
-      margin:0;
-      font-size: 12px;
-    }
-    .last-timestamp {
-      position:absolute;
-      top:14px;
-      right:8px;
-      font-size:12px;
-      font-weight: 500;
-      color:gray;
-    }
-  }
-}
-.avatar {
-  cursor:pointer;
-  height:56px;
-  width:56px;
-  display:inline-block;
-  margin:10px;
-  margin-right:14px;
-  float:left;
-  clear:both;
-  background-color:whitesmoke;
-}
-
-.search {
-  padding:10px;
-  border-bottom:1px solid whitesmoke;
-  input[type=search] {
-    box-sizing: border-box;
-    font-size:12px;
-    outline:0;
-    width:100%;
-    margin:0;
-    letter-spacing: 0.25px;
-    padding:4px 8px;
-    border:1px solid lightgray;
-  }
-}
-

+ 2 - 39
stylesheets/index.css

@@ -1,41 +1,3 @@
-.clearfix:before, .clearfix:after { content: "\0020"; display: block; height: 0; overflow: hidden; }
-.clearfix:after { clear: both; }
-.clearfix { zoom: 1; }
-
-body {
-  min-width: 320px;
-  min-height: 500px;
-}
-.number.error {
-  background-color: #ffdddd;
-}
-
-.gutter {
-  padding-bottom: 0;
-  overflow: hidden;
-}
-
-#contacts {
-  overflow-y: scroll;
-}
-#contacts::-webkit-scrollbar {
-  display: none;
-}
-
-.contact.selected {
-  background-color: aliceblue;
-}
-
-.gutter .contact .avatar {
-  background-position: center;
-  background-size: cover;
-}
-
-.conversation {
-  margin: 0;
-  padding: 0;
-}
-
 ul.discussion {
   margin: 0;
   padding: 10px;
@@ -115,6 +77,7 @@ img.preview {
 ul.country-list {
   min-width: 197px !important;
 }
+<<<<<<< HEAD
 
 div.attachments {
   width: 95% !important;
@@ -211,4 +174,4 @@ input.file-input {
     font-size: 1em;
     position: relative;
   }
-}
+}

+ 84 - 89
stylesheets/manifest.css

@@ -81,99 +81,94 @@ body {
 
   .gutter .search {
     display: block; } }
-@media screen and (min-width: 320px) {
-  .gutter {
-    width: 64px;
+.gutter {
+  width: 100%;
+  float: left;
+  border-right: 1px solid lightgray;
+  position: relative;
+  box-sizing: border-box;
+  overflow: scroll;
+  background-color: white;
+  padding-bottom: 80px;
+  z-index: 100; }
+  .gutter .contact {
+    cursor: pointer;
     float: left;
-    border-right: 1px solid lightgray;
-    position: relative;
-    box-sizing: border-box;
-    height: 458px;
-    overflow: scroll;
-    background-color: white;
-    padding-bottom: 80px; }
-    .gutter .contact {
+    width: 100%;
+    border-bottom: 1px solid whitesmoke;
+    color: #333; }
+    .gutter .contact:hover {
+      background-color: whitesmoke;
+      margin-top: -1px;
+      border-bottom: 1px solid lightgray;
+      border-top: 1px solid lightgray; }
+    .gutter .contact.active {
+      background-color: #ecfcff;
+      margin-top: -1px;
+      border-bottom: 1px solid lightgray;
+      border-top: 1px solid lightgray; }
+    .gutter .contact .avatar {
+      height: 42px;
+      width: 42px;
+      border-radius: 42px;
       cursor: pointer;
+      display: inline-block;
+      margin: 10px;
+      margin-right: 14px;
       float: left;
-      width: 100%;
-      border-bottom: 1px solid whitesmoke;
-      color: #333; }
-      .gutter .contact:hover {
-        background-color: whitesmoke;
-        margin-top: -1px;
-        border-bottom: 1px solid lightgray;
-        border-top: 1px solid lightgray; }
-      .gutter .contact.active {
-        background-color: #ecfcff;
-        margin-top: -1px;
-        border-bottom: 1px solid lightgray;
-        border-top: 1px solid lightgray; }
-      .gutter .contact .avatar {
-        height: 42px;
-        width: 42px;
-        border-radius: 42px;
-        cursor: pointer;
-        display: inline-block;
-        margin: 10px;
-        margin-right: 14px;
-        float: left;
-        clear: both;
-        background-color: whitesmoke; }
-      .gutter .contact .contact-details {
-        display: none; } }
-@media screen and (min-width: 480px) {
-  .gutter {
-    width: 240px;
-    height: auto;
-    z-index: 100; }
-    .gutter .search {
-      padding: 10px;
-      border-bottom: 1px solid whitesmoke; }
-      .gutter .search input[type=search] {
-        box-sizing: border-box;
-        font-size: 12px;
-        outline: 0;
-        width: 100%;
-        margin: 0;
-        letter-spacing: 0.25px;
-        padding: 4px 8px;
-        border: 1px solid lightgray; }
-      .gutter .search.d6 {
-        display: block; }
-    .gutter .contact .avatar {
-      height: 56px;
-      width: 56px; }
+      clear: both;
+      background-color: whitesmoke; }
     .gutter .contact .contact-details {
-      display: block;
-      position: relative;
-      width: 156px;
-      float: left;
-      text-align: left; }
-      .gutter .contact .contact-details h3 {
-        font-size: 13px;
-        margin-bottom: 4px; }
-      .gutter .contact .contact-details .contact-name {
-        width: 105px;
-        white-space: nowrap;
-        overflow: hidden;
-        text-overflow: ellipsis; }
-      .gutter .contact .contact-details .last-message {
-        color: #999999;
-        letter-spacing: 0.15px;
-        -webkit-text-stroke: 0.2px;
-        margin: 0;
-        font-size: 12px;
-        width: 150px;
-        white-space: nowrap;
-        overflow: hidden;
-        text-overflow: ellipsis; }
-      .gutter .contact .contact-details .last-timestamp {
-        position: absolute;
-        top: 14px;
-        right: 8px;
-        font-size: 12px;
-        font-weight: 500;
-        color: gray; } }
+      display: none; }
+  .gutter .search {
+    padding: 10px;
+    border-bottom: 1px solid whitesmoke; }
+    .gutter .search input[type=search] {
+      box-sizing: border-box;
+      font-size: 12px;
+      outline: 0;
+      width: 100%;
+      margin: 0;
+      letter-spacing: 0.25px;
+      padding: 4px 8px;
+      border: 1px solid lightgray; }
+    .gutter .search.d6 {
+      display: block; }
+  .gutter .contact .avatar {
+    height: 56px;
+    width: 56px; }
+  .gutter .contact .contact-details {
+    display: block;
+    position: relative;
+    width: 156px;
+    float: left;
+    text-align: left; }
+    .gutter .contact .contact-details h3 {
+      font-size: 13px;
+      margin-bottom: 4px; }
+    .gutter .contact .contact-details .contact-name {
+      width: 105px;
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis; }
+    .gutter .contact .contact-details .last-message {
+      color: #999999;
+      letter-spacing: 0.15px;
+      -webkit-text-stroke: 0.2px;
+      margin: 0;
+      font-size: 12px;
+      width: 150px;
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis; }
+    .gutter .contact .contact-details .last-timestamp {
+      position: absolute;
+      top: 14px;
+      right: 8px;
+      font-size: 12px;
+      font-weight: 500;
+      color: gray; }
+
 .conversation {
   margin-top: 10px;
   width: 100%;

文件差异内容过多而无法显示
+ 0 - 0
stylesheets/manifest.css.map


+ 94 - 106
stylesheets/view/_gutter.scss

@@ -1,119 +1,107 @@
-@media #{$D7} {
-  .gutter {
-    width:64px;
+.gutter {
+  width:100%;
+  float:left;
+  border-right:1px solid lightgray;
+  position:relative;
+  box-sizing: border-box;
+  overflow: scroll;
+  background-color:white;
+  padding-bottom:80px;
+
+  .contact {
+    cursor:pointer;
     float:left;
-    border-right:1px solid lightgray;
-    position:relative;
-    box-sizing: border-box;
-    height:458px;
-    overflow: scroll;
-    background-color:white;
-    padding-bottom:80px;
-    .search {
-      //display:none;
+    width:100%;
+    border-bottom:1px solid whitesmoke;
+    color:#333;
+    &:hover {
+      background-color:whitesmoke;
+      margin-top:-1px;
+      border-bottom:1px solid lightgray;
+      border-top:1px solid lightgray;
+    }
+    &.active {
+      background-color:$lightblue;
+      margin-top:-1px;
+      border-bottom:1px solid lightgray;
+      border-top:1px solid lightgray;
     }
-    .contact {
+    .avatar {
+      height:42px;
+      width:42px;
+      border-radius:42px;
       cursor:pointer;
+      display:inline-block;
+      margin:10px;
+      margin-right:14px;
       float:left;
-      width:100%;
-      border-bottom:1px solid whitesmoke;
-      color:#333;
-      &:hover {
-        background-color:whitesmoke;
-        margin-top:-1px;
-        border-bottom:1px solid lightgray;
-        border-top:1px solid lightgray;
-      }
-      &.active {
-        background-color:$lightblue;
-        margin-top:-1px;
-        border-bottom:1px solid lightgray;
-        border-top:1px solid lightgray;
-      }
-      .avatar {
-        height:42px;
-        width:42px;
-        border-radius:42px;
-        cursor:pointer;
-        display:inline-block;
-        margin:10px;
-        margin-right:14px;
-        float:left;
-        clear:both;
-        background-color:whitesmoke;
-      }
-      .contact-details {
-        display:none;
-      }
+      clear:both;
+      background-color:whitesmoke;
+    }
+    .contact-details {
+      display:none;
     }
   }
-}
-
-@media #{$D6} {
 
-  .gutter {
-    width:240px;
-    height:auto;
-    z-index:100;
-    .search {
-      padding:10px;
-      border-bottom:1px solid whitesmoke;
-      input[type=search] {
-        box-sizing: border-box;
-        font-size:12px;
-        outline:0;
-        width:100%;
-        margin:0;
-        letter-spacing: 0.25px;
-        padding:4px 8px;
-        border:1px solid lightgray;
+  z-index:100;
+  .search {
+    padding:10px;
+    border-bottom:1px solid whitesmoke;
+    input[type=search] {
+      box-sizing: border-box;
+      font-size:12px;
+      outline:0;
+      width:100%;
+      margin:0;
+      letter-spacing: 0.25px;
+      padding:4px 8px;
+      border:1px solid lightgray;
+    }
+    &.d6 {
+      display:block;
+    }
+  }
+  .contact {
+    .avatar {
+      height:56px;
+      width:56px;
+    }
+    .contact-details {
+      display:block;
+      position:relative;
+      width:156px;
+      float:left;
+      text-align: left;
+      h3 {
+        font-size:13px;
+        margin-bottom:4px;
       }
-      &.d6 {
-        display:block;
+      .contact-name {
+        width: 105px;
+        white-space: nowrap;
+        overflow: hidden;
+        text-overflow: ellipsis;
       }
-    }
-    .contact {
-      .avatar {
-        height:56px;
-        width:56px;
+      .last-message {
+        color:lighten(#333, 40%);
+        letter-spacing:0.15px;
+        -webkit-text-stroke: 0.2px;
+        margin:0;
+        font-size: 12px;
+        width: 150px;
+        white-space: nowrap;
+        overflow: hidden;
+        text-overflow: ellipsis;
       }
-      .contact-details {
-        display:block;
-        position:relative;
-        width:156px;
-        float:left;
-        text-align: left;
-        h3 {
-          font-size:13px;
-          margin-bottom:4px;
-        }
-        .contact-name {
-          width: 105px;
-          white-space: nowrap;
-          overflow: hidden;
-          text-overflow: ellipsis;
-        }
-        .last-message {
-          color:lighten(#333, 40%);
-          letter-spacing:0.15px;
-          -webkit-text-stroke: 0.2px;
-          margin:0;
-          font-size: 12px;
-          width: 150px;
-          white-space: nowrap;
-          overflow: hidden;
-          text-overflow: ellipsis;
-        }
-        .last-timestamp {
-          position:absolute;
-          top:14px;
-          right:8px;
-          font-size:12px;
-          font-weight: 500;
-          color:gray;
-        }
+      .last-timestamp {
+        position:absolute;
+        top:14px;
+        right:8px;
+        font-size:12px;
+        font-weight: 500;
+        color:gray;
       }
     }
-
   }
-}
+
+}

部分文件因为文件数量过多而无法显示