Browse Source

Redesigned threads lists. #109

Ralfp 12 years ago
parent
commit
950327c543

+ 2 - 0
misago/apps/watchedthreads/views.py

@@ -18,6 +18,8 @@ def watched_threads(request, page=0, new=False):
     if not request.settings['enable_private_threads']:
         readable_forums.remove(Forum.objects.special_pk('private_threads'))
     queryset = WatchedThread.objects.filter(user=request.user).filter(forum_id__in=readable_forums).select_related('thread').filter(thread__moderated=False).filter(thread__deleted=False)
+    if request.settings['avatars_on_threads_list']:
+        queryset = queryset.prefetch_related('thread__last_poster')
     if new:
         queryset = queryset.filter(last_read__lt=F('thread__last'))
     count = queryset.count()

+ 22 - 17
static/cranefly/css/cranefly.css

@@ -1020,10 +1020,8 @@ a.btn-link:hover,a.btn-link:active,a.btn-link:focus{opacity:0.9;filter:alpha(opa
 .forum-map-category.forum-map-category-important .header{background-color:#cf402e;border:1px solid #a53325;}.forum-map-category.forum-map-category-important .header h2{color:#ffffff;text-shadow:0px 1px 0px #672017;}.forum-map-category.forum-map-category-important .header h2 small{color:#280c09;text-shadow:none;}
 .forum-map-category.forum-map-category-inverse .header{background-color:#333333;border:1px solid #1a1a1a;}.forum-map-category.forum-map-category-inverse .header h2{color:#eeeeee;text-shadow:0px 1px 0px #000000;}.forum-map-category.forum-map-category-inverse .header h2 small{color:#b3b3b3;text-shadow:none;}
 .forum-map-category.forum-map-category-info .header{background-color:#3c85a3;border:1px solid #2e677e;}.forum-map-category.forum-map-category-info .header h2{color:#ffffff;text-shadow:0px 1px 0px #1a3946;}.forum-map-category.forum-map-category-info .header h2 small{color:#1a3946;text-shadow:none;}
-.watched-threads table .watched-thread-flags{overflow:auto;}.watched-threads table .watched-thread-flags form{float:right;margin:0px;padding:0px;}.watched-threads table .watched-thread-flags form .btn{float:right;padding:3px 5px;padding-bottom:0px;margin-right:16px;}
-.watched-threads table .thread-replies{color:#999999;text-align:right;}
-.watched-threads table .thread-forum a:link,.watched-threads table .thread-forum a:visited{color:#555555;font-weight:bold;}
-.watched-threads table .thread-forum a:active,.watched-threads table .thread-forum a:hover{color:#333333;}
+.watched-threads .thread-last-reply{border-left:none !important;padding-left:0px !important;}
+.watched-threads .thread-options{float:right;overflow:auto;position:relative;bottom:2px;}.watched-threads .thread-options form{display:inline-block;float:left;margin:0px;padding:0px;overflow:auto;}.watched-threads .thread-options form .btn{float:right;padding:3px 5px;padding-bottom:0px;margin-left:16px;}
 .user-alerts td{vertical-align:middle;}.user-alerts td.alert-icon .label{background-color:#555555;border:1px solid #2f2f2f;border-radius:3px;padding:4px;padding-top:3px;}.user-alerts td.alert-icon .label i{background-image:url("../img/glyphicons-halflings-white.png");}
 .user-alerts td.alert-icon .label.label-warning{background-color:#cf402e;border:1px solid #902d20;}
 .user-alerts td.alert-message{color:#555555;font-size:16.8px;}.user-alerts td.alert-message a:link,.user-alerts td.alert-message a:visited{color:#333333;font-weight:bold;}
@@ -1083,19 +1081,26 @@ a.btn-link:hover,a.btn-link:active,a.btn-link:focus{opacity:0.9;filter:alpha(opa
 .forum-subforums-list.forum-subforums-important .header{background-color:#cf402e;border:1px solid #a53325;}.forum-subforums-list.forum-subforums-important .header h2{color:#ffffff;text-shadow:0px 1px 0px #672017;}.forum-subforums-list.forum-subforums-important .header h2 small{color:#280c09;text-shadow:none;}
 .forum-subforums-list.forum-subforums-inverse .header{background-color:#333333;border:1px solid #1a1a1a;}.forum-subforums-list.forum-subforums-inverse .header h2{color:#eeeeee;text-shadow:0px 1px 0px #000000;}.forum-subforums-list.forum-subforums-inverse .header h2 small{color:#b3b3b3;text-shadow:none;}
 .forum-subforums-list.forum-subforums-info .header{background-color:#3c85a3;border:1px solid #2e677e;}.forum-subforums-list.forum-subforums-info .header h2{color:#ffffff;text-shadow:0px 1px 0px #1a3946;}.forum-subforums-list.forum-subforums-info .header h2 small{color:#1a3946;text-shadow:none;}
-.forum-threads-list{background-color:#ffffff;border:1px solid #d5d5d5;border-radius:2px;-webkit-box-shadow:0px 0px 0px 3px #eeeeee;-moz-box-shadow:0px 0px 0px 3px #eeeeee;box-shadow:0px 0px 0px 3px #eeeeee;margin-bottom:20px;}.forum-threads-list table{margin:0px;}.forum-threads-list table th{background-color:#fbfbfb;border-bottom:1px solid #eeeeee;padding:2px 10px;color:#999999;font-size:11.9px;}
-.forum-threads-list table td{vertical-align:middle;}.forum-threads-list table td.threads-list-empty{padding:11px 19px;font-size:17.5px;text-align:center;}
-.forum-threads-list table td .thread-icon:link,.forum-threads-list table td .thread-icon:active,.forum-threads-list table td .thread-icon:visited,.forum-threads-list table td .thread-icon:hover{background-color:#555555;border:1px solid #2f2f2f;border-radius:3px;margin-right:7px;padding:3px 4px;}.forum-threads-list table td .thread-icon:link.thread-new,.forum-threads-list table td .thread-icon:active.thread-new,.forum-threads-list table td .thread-icon:visited.thread-new,.forum-threads-list table td .thread-icon:hover.thread-new{background-color:#cf402e;border:1px solid #902d20;}
-.forum-threads-list table td .thread-icon i{background-image:url("../img/glyphicons-halflings-white.png");}
-.forum-threads-list table td .thread-name{color:#333333;font-weight:bold;}
-.forum-threads-list table td .thread-details,.forum-threads-list table td .thread-last-reply{color:#999999;}.forum-threads-list table td .thread-details a:link,.forum-threads-list table td .thread-last-reply a:link,.forum-threads-list table td .thread-details a:visited,.forum-threads-list table td .thread-last-reply a:visited{color:#333333;}
-.forum-threads-list table td .thread-details{font-size:10.5px;}
-.forum-threads-list table td .thread-flags{float:right;margin:0px;opacity:0.8;filter:alpha(opacity=80);padding:0px;}.forum-threads-list table td .thread-flags li{margin-left:3px;float:left;}
-.forum-threads-list table td .thread-rating{background-color:#eeeeee;border-radius:3px;padding:4px;color:#999999;font-size:17.5px;font-weight:bold;text-align:center;}.forum-threads-list table td .thread-rating.thread-rating-negative,.forum-threads-list table td .thread-rating.thread-rating-positive{color:#ffffff;}
-.forum-threads-list table td .thread-rating.thread-rating-negative{background-color:#cf402e;}
-.forum-threads-list table td .thread-rating.thread-rating-positive{background-color:#46a546;}
-.forum-threads-list table th.check-cell,.forum-threads-list table td.check-cell{width:1%;text-align:center;vertical-align:middle;}.forum-threads-list table th.check-cell .checkbox,.forum-threads-list table td.check-cell .checkbox{margin:0px;padding:0px;}.forum-threads-list table th.check-cell .checkbox input,.forum-threads-list table td.check-cell .checkbox input{margin:0px;padding:0px;position:relative;top:3px;}
-.forum-threads-list table th.check-cell input{right:2px;}
+.forum-threads-list{background-color:#ffffff;border:1px solid #d5d5d5;border-radius:2px;-webkit-box-shadow:0px 0px 0px 3px #eeeeee;-moz-box-shadow:0px 0px 0px 3px #eeeeee;box-shadow:0px 0px 0px 3px #eeeeee;margin-bottom:20px;}.forum-threads-list .header{background-color:#fbfbfb;border:1px solid #d5d5d5;border-radius:2px 2px 0px 0px;margin:-1px;margin-bottom:0px;padding-bottom:1px;overflow:auto;color:#999999;font-weight:bold;font-size:11.9px;}.forum-threads-list .header .row-fluid>div{min-height:auto;padding:2px 10px;}
+.forum-threads-list .header .row-fluid .thread-replies{float:left;width:106px;}
+.forum-threads-list .header .row-fluid .thread-last{float:left;}
+.forum-threads-list .header .check-cell label{margin:0px;}
+.forum-threads-list .thread-row{border-bottom:1px solid #d5d5d5;height:24px;overflow:hidden;padding:9.9px 0px;}.forum-threads-list .thread-row .row-fluid>div{min-height:auto;padding:2px 10px;padding-bottom:0px;}
+.forum-threads-list .thread-row.thread-last{border-bottom:none;}.forum-threads-list .thread-row.thread-last>div{padding-bottom:1px;}
+.forum-threads-list .thread-row .thread-icon{background-color:#555555;border:1px solid #3b3b3b;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;display:block;float:left;margin:-2px 0px;margin-left:-1px;padding:1px 4px;}.forum-threads-list .thread-row .thread-icon:hover,.forum-threads-list .thread-row .thread-icon:active{opacity:1;filter:alpha(opacity=100);}
+.forum-threads-list .thread-row .thread-icon i{background-image:url("../img/glyphicons-halflings-white.png");}
+.forum-threads-list .thread-row.thread-new .thread-icon{background-color:#cf402e;border:1px solid #a53325;}
+.forum-threads-list .thread-row.thread-new .thread-name{color:#333333 !important;}
+.forum-threads-list .thread-row.threads-list-empty{padding:11px 19px;font-size:17.5px;text-align:center;}
+.forum-threads-list .thread-row .thread-name{margin-left:10px;color:#5e5e5e;font-size:16px;font-weight:bold;}
+.forum-threads-list .thread-row .thread-details,.forum-threads-list .thread-row .thread-last-reply{color:#999999;}.forum-threads-list .thread-row .thread-details a:link,.forum-threads-list .thread-row .thread-last-reply a:link,.forum-threads-list .thread-row .thread-details a:visited,.forum-threads-list .thread-row .thread-last-reply a:visited{color:#333333;}
+.forum-threads-list .thread-row .thread-details{font-size:10.5px;}
+.forum-threads-list .thread-row .thread-flags{float:right;margin:0px;padding:0px;position:relative;right:-26px;}.forum-threads-list .thread-row .thread-flags li{float:left;margin-left:3px;}
+.forum-threads-list .thread-row .thread-activity{border-left:1px dotted #e0e0e0;color:#999999;}.forum-threads-list .thread-row .thread-activity a:link,.forum-threads-list .thread-row .thread-activity a:active,.forum-threads-list .thread-row .thread-activity a:visited,.forum-threads-list .thread-row .thread-activity a:hover{color:#555555;font-weight:bold;}
+.forum-threads-list .thread-row .thread-activity .thread-replies{float:left;margin-right:14px;opacity:0.6;filter:alpha(opacity=60);width:76px;color:#333333;font-size:17.5px;font-weight:bold;text-align:right;}.forum-threads-list .thread-row .thread-activity .thread-replies i{position:relative;top:2px;}
+.forum-threads-list .thread-row .thread-activity .thread-last-reply{border-left:1px dotted #e0e0e0;float:left;padding-left:14px;}.forum-threads-list .thread-row .thread-activity .thread-last-reply .thread-last-avatar img{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;margin:-6px 0px;position:relative;bottom:1px;width:28px;height:28px;}
+.forum-threads-list .thread-row .thread-activity .thread-select{background-color:#f2f2f2;display:block;float:right;margin:-12px -11px;margin-left:0px;width:29px;height:44px;}.forum-threads-list .thread-row .thread-activity .thread-select:hover,.forum-threads-list .thread-row .thread-activity .thread-select:focus,.forum-threads-list .thread-row .thread-activity .thread-select:active{background-color:#0088cc;}
+.forum-threads-list .thread-row .thread-activity .thread-select input{margin:0px;position:relative;right:2px;top:16px;}
 .forum-threads-list .threads-actions{background-color:#fbfbfb;border-top:1px solid #d5d5d5;border-radius:0px 0px 2px 2px;overflow:auto;padding:4px;color:#999999;font-size:11.9px;}.forum-threads-list .threads-actions form{margin-bottom:0px;}
 .forum-threads-extra{overflow:auto;}.forum-threads-extra.extra-top{margin-bottom:20px;}
 .forum-threads-extra .threads-signin-message{float:right;}.forum-threads-extra .threads-signin-message a:link,.forum-threads-extra .threads-signin-message a:visited{color:#333333;}

+ 156 - 82
static/cranefly/css/cranefly/forum.less

@@ -304,123 +304,197 @@
   .box-shadow(0px 0px 0px 3px @categoryShadow);
   margin-bottom: @baseLineHeight;
 
-  table {
-    margin: 0px;
+  .header {
+    background-color: @categoryHeader;
+    border: 1px solid @categoryBorder;
+    border-radius: @borderRadiusSmall @borderRadiusSmall 0px 0px;
+    margin: -1px;
+    margin-bottom: 0px;
+    padding-bottom: 1px;
+    overflow: auto;
 
-    th {
-      background-color: @bodyBackground;
-      border-bottom: 1px solid @grayLighter;
-      padding: @paddingSmall;
+    color: @grayLight;
+    font-weight: bold;
+    font-size: @fontSizeSmall;
 
-      color: @grayLight;
-      font-size: @fontSizeSmall;
+    .row-fluid {
+      &>div {
+        min-height: auto;
+        padding: @paddingSmall;
+      }
+
+      .thread-replies {
+        float: left;
+        width: 106px;
+      }
+
+      .thread-last {
+        float: left;
+      }
     }
 
-    td {
-      vertical-align: middle;
+    .check-cell {
+      label {
+        margin: 0px;
+      }
+    }
+  }
 
-      &.threads-list-empty {
-        padding: @paddingLarge;
+  .thread-row {
+    border-bottom: 1px solid @categoryBorder;
+    height: 24px;
+    overflow: hidden;
+    padding: (@fontSizeSmall - 2px) 0px;
+
+    .row-fluid {
+      &>div {
+        min-height: auto;
+        padding: @paddingSmall;
+        padding-bottom: 0px;
+      }
+    }
 
-        font-size: @fontSizeLarge;
-        text-align: center;
+    &.thread-last {
+      border-bottom: none;
+
+      &>div {
+        padding-bottom: 1px;
       }
+    }
 
-      .thread-icon {
-        &:link, &:active, &:visited, &:hover {
-          background-color: @itemOldColor;
-          border: 1px solid darken(@itemOldColor, 15%);
-          border-radius: @baseBorderRadius;
-          margin-right: @baseFontSize / 2;
-          padding: 3px 4px;
-
-          &.thread-new {
-            background-color: @itemNewColor;
-            border: 1px solid darken(@itemNewColor, 15%);
-          }
-        }
+    .thread-icon {
+      background-color: @itemOldColor;
+      border: 1px solid darken(@itemOldColor, 10%);
+      .border-radius(@baseBorderRadius);
+      display: block;
+      float: left;
+      margin: -2px 0px;
+      margin-left: -1px;
+      padding: 1px 4px;
 
-        i {
-          background-image: url("@{iconWhiteSpritePath}");
-        }
+      &:hover, &:active {
+        .opacity(100);
       }
 
-      .thread-name {
-        color: @textColor;
-        font-weight: bold;
+      i {
+        background-image: url("@{iconWhiteSpritePath}");
       }
+    }
 
-      .thread-details, .thread-last-reply {
-        color: @grayLight;
+    &.thread-new {
+      .thread-icon {
+        background-color: @itemNewColor;
+        border: 1px solid darken(@itemNewColor, 10%);
+      }
 
-        a:link, a:visited {
-          color: @textColor;
-        }
+      .thread-name {
+        color: @textColor !important;
       }
+    }
+
+    &.threads-list-empty {
+      padding: @paddingLarge;
+
+      font-size: @fontSizeLarge;
+      text-align: center;
+    }
+
+    .thread-name {
+      margin-left: 10px;
+
+      color: lighten(@textColor, 17%);
+      font-size: @baseFontSize + 2px;
+      font-weight: bold;
+    }
+
+    .thread-details, .thread-last-reply {
+      color: @grayLight;
 
-      .thread-details {
-        font-size: @fontSizeMini;
+      a:link, a:visited {
+        color: @textColor;
       }
+    }
 
-      .thread-flags {
-        float: right;
-        margin: 0px;
-        .opacity(80);
-        padding: 0px;
+    .thread-details {
+      font-size: @fontSizeMini;
+    }
 
-        li {
-          margin-left: 3px;
-          float: left;
-        }
+    .thread-flags {
+      float: right;
+      margin: 0px;
+      padding: 0px;
+      position: relative;
+      right: -26px;
+
+      li {
+        float: left;
+        margin-left: 3px;
       }
+    }
 
-      .thread-rating {
-        background-color: @grayLighter;
-        border-radius: @baseBorderRadius;
-        padding: 4px;
+    .thread-activity {
+      border-left: 1px dotted darken(@categoryBackground, 12%);
 
-        color: @grayLight;
-        font-size: @fontSizeLarge;
+      color: @grayLight;
+
+      a:link, a:active, a:visited, a:hover {
+        color: @gray;
         font-weight: bold;
-        text-align: center;
+      }
 
-        &.thread-rating-negative, &.thread-rating-positive {
-          color: @white;
-        }
+      .thread-replies {
+        float: left;
+        margin-right: @baseFontSize;
+        .opacity(60);
+        width: 76px;
 
-        &.thread-rating-negative {
-          background-color: @red;
-        }
+        color: @textColor;
+        font-size: @fontSizeLarge;
+        font-weight: bold;
+        text-align: right;
 
-        &.thread-rating-positive {
-          background-color: @green;
+        i {
+          position: relative;
+          top: 2px;
         }
       }
-    }
 
-    th, td {
-      &.check-cell {
-        width: 1%;
-        text-align: center;
-        vertical-align: middle;
-
-        .checkbox {
-          margin: 0px;
-          padding: 0px;
+      .thread-last-reply {
+        border-left: 1px dotted darken(@categoryBackground, 12%);
+        float: left;
+        padding-left: @baseFontSize;
 
-          input {
-            margin: 0px;
-            padding: 0px;
+        .thread-last-avatar {
+          img {
+            .border-radius(@baseBorderRadius);
+            margin: -6px 0px;
             position: relative;
-            top: 3px;
+            bottom: 1px;
+            width: 28px;
+            height: 28px;
           }
         }
       }
-    }
 
-    th.check-cell {
-      input{
-        right: 2px;
+      .thread-select {
+        background-color: darken(@categoryBackground, 5%);
+        display: block;
+        float: right;
+        margin: -12px -11px;
+        margin-left: 0px;
+        width: 29px;
+        height: 44px;
+
+        &:hover, &:focus, &:active {
+          background-color: @linkColor;
+        }
+
+        input {
+          margin: 0px;
+          position: relative;
+          right: 2px;
+          top: 16px;
+        }
       }
     }
   }

+ 20 - 28
static/cranefly/css/cranefly/watchedthreads.less

@@ -2,37 +2,29 @@
 // -------------------------
 
 .watched-threads {
-  table {
-    .watched-thread-flags {
-      overflow: auto;
-
-      form {
-        float: right;
-        margin: 0px;
-        padding: 0px;
+  .thread-last-reply {
+    border-left: none !important;
+    padding-left: 0px !important;
+  }
 
-        .btn {
-          float: right;
-          padding: 3px 5px;
-          padding-bottom: 0px;
-          margin-right: @baseFontSize + 2px;
-        }
-      }
-    }
-    
-    .thread-replies {
-      color: @grayLight;
-      text-align: right;
-    }
+  .thread-options {
+    float: right;
+    overflow: auto;
+    position: relative;
+    bottom: 2px;
 
-    .thread-forum {
-      a:link, a:visited {
-        color: @gray;
-        font-weight: bold;
-      }
+    form {
+      display: inline-block;
+      float: left;
+      margin: 0px;
+      padding: 0px;
+      overflow: auto;
 
-      a:active, a:hover {
-        color: @textColor;
+      .btn {
+        float: right;
+        padding: 3px 5px;
+        padding-bottom: 0px;
+        margin-left: @baseFontSize + 2px;
       }
     }
   }

+ 66 - 49
templates/cranefly/new_threads.html

@@ -14,56 +14,73 @@
 <div class="container container-primary">
   {% if threads %}
   <div class="forum-threads-list">
-    <table class="table">
-      <thead>
-        <tr>
-          <th>{% trans %}Thread{% endtrans %}</th>
-          <th class="span1">{% trans %}Rating{% endtrans %}</th>
-          <th class="span5">{% trans %}Activity{% endtrans %}</th>
-          {% if user.is_authenticated() and list_form %}
-          <th class="check-cell"><label class="checkbox"><input type="checkbox" class="checkbox-master"></label></th>
+    <div class="header">
+      <div class="row-fluid">
+        <div class="span7">{% trans %}Thread{% endtrans %}</div>
+        <div class="span5 thread-activity">
+          <div class="thread-replies">{% trans %}Replies{% endtrans %}</div>
+          <div class="thread-last">{% trans %}Last Reply{% endtrans %}</div>
+        </div>
+      </div>
+    </div>
+    {% for thread in threads %}
+    <div class="thread-row{% if thread.pk == 2 or not thread.is_read %} thread-new{% endif %}{% if loop.last %} thread-last{% endif %}">
+      <div class="row-fluid">
+        <div class="span7">
+          {% if thread.is_read and not thread.pk == 2 %}
+          <a href="{% url 'thread_new' thread=thread.pk, slug=thread.slug %}" class="thread-icon thread-icon-last tooltip-top" title="{% trans %}Click to see last post{% endtrans %}"><i class="icon-asterisk"></i></a>
+          {% else %}
+          <a href="{% url 'thread_new' thread=thread.pk, slug=thread.slug %}" class="thread-icon thread-icon-new tooltip-top" title="{% trans %}Click to see first unread post{% endtrans %}"><i class="icon-fire"></i></a>
           {% endif %}
-        </tr>
-      </thead>
-      <tbody>
-        {% for thread in threads %}
-        <tr>
-          <td>
-            <a href="{% url 'thread_new' thread=thread.pk, slug=thread.slug %}" class="thread-icon{% if not thread.is_read %} thread-new{% endif %} tooltip-top" title="{% if not thread.is_read -%}
-            {% trans %}Click to see first unread post{% endtrans %}
-            {%- else -%}
-            {% trans %}Click to see last post{% endtrans %}
-            {%- endif %}"><i class="icon-comment"></i></a>
-            <a href="{% url 'thread' thread=thread.pk, slug=thread.slug %}" class="thread-name">{{ thread.name }}</a>
-            <span class="thread-details">
-              {% trans user=thread_starter(thread), forum=thread_forum(thread), start=thread.start|reltimesince|low %}by {{ user }} in {{ forum }} {{ start }}{% endtrans %}
-            </span>
-            <ul class="unstyled thread-flags">
-              {% if thread.weight == 2 %}
-              <li><i class="icon-star tooltip-top" title="{% trans %}This thread is an annoucement{% endtrans %}"></i></li>
-              {% endif %}
-              {% if thread.weight == 1 %}
-              <li><i class="icon-star-empty tooltip-top" title="{% trans %}This thread is sticky{% endtrans %}"></i></li>
-              {% endif %}
-              {% if thread.closed %}
-              <li><i class="icon-lock tooltip-top" title="{% trans %}This thread is closed{% endtrans %}"></i></li>
+
+          <a href="{% url 'thread' thread=thread.pk, slug=thread.slug %}" class="thread-name">{{ thread.name }}</a>
+          <span class="thread-details">
+            {% trans user=thread_starter(thread), forum=thread_forum(thread) %}by {{ user }} in {{ forum }}{% endtrans %}
+          </span>
+
+          <ul class="unstyled thread-flags">
+            {% if thread.replies_reported %}
+            <li><i class="icon-warning-sign tooltip-top" title="{% trans %}This thread has reported replies{% endtrans %}"></i></li>
+            {% endif %}
+            {% if thread.replies_moderated %}
+            <li><i class="icon-question-sign tooltip-top" title="{% trans %}This thread has unreviewed replies{% endtrans %}"></i></li>
+            {% endif %}
+            {% if thread.weight == 2 %}
+            <li><i class="icon-star tooltip-top" title="{% trans %}This thread is an annoucement{% endtrans %}"></i></li>
+            {% endif %}
+            {% if thread.weight == 1 %}
+            <li><i class="icon-star-empty tooltip-top" title="{% trans %}This thread is sticky{% endtrans %}"></i></li>
+            {% endif %}
+            {% if thread.moderated  %}
+            <li><i class="icon-eye-close tooltip-top" title="{% trans %}This thread awaits review{% endtrans %}"></i></li>
+            {% endif %}
+            {% if thread.deleted %}
+            <li><i class="icon-trash tooltip-top" title="{% trans %}This thread is deleted{% endtrans %}"></i></li>
+            {% endif %}
+            {% if thread.closed %}
+            <li><i class="icon-lock tooltip-top" title="{% trans %}This thread is closed{% endtrans %}"></i></li>
+            {% endif %}
+          </ul>
+        </div>
+        <div class="span5 thread-activity">
+          <div class="thread-replies tooltip-top" title="{{ replies(thread.replies) }}">{{ thread.replies|intcomma }} <i class="icon-comment"></i></div>
+
+          <div class="thread-last-reply">
+            {% if settings.avatars_on_threads_list %}
+            <span class="thread-last-avatar">
+              {% if thread.last_poster_id %}
+              <a href="{% url 'user' user=thread.last_poster.pk, username=thread.last_poster.username_slug %}"><img src="{{ thread.last_poster.get_avatar(30) }}" alt=""></a>
+              {% else %}
+              <img src="{{ macros.avatar_guest(40) }}" alt="" class="user-avatar">
               {% endif %}
-            </ul>
-          </td>
-          <td>
-            <div class="thread-rating{% if (thread.upvotes-thread.downvotes) > 0 %} thread-rating-positive{% elif (thread.upvotes-thread.downvotes) < 0 %} thread-rating-negative{% endif %}">
-              {% if (thread.upvotes-thread.downvotes) > 0 %}+{% elif (thread.upvotes-thread.downvotes) < 0 %}-{% endif %}{{ (thread.upvotes-thread.downvotes)|abs|intcomma }}
-            </div>
-          </td>
-          <td>
-            <div class="thread-last-reply">
-              {{ replies(thread.replies) }} - {% trans user=thread_reply(thread), last=thread.last|reltimesince|low %}last by {{ user }} {{ last }}{% endtrans %}
-            </div>
-          </td>
-        </tr>
-        {% endfor %}
-      </tbody>
-    </table>
+            </span>
+            {% endif %}
+            {{ thread_reply(thread) }}, {{ thread.last|reldate|low }}
+          </div>
+        </div>
+      </div>
+    </div>
+    {% endfor %}
   </div>
   {{ pager() }}
   {% else %}
@@ -74,7 +91,7 @@
 
 
 {% macro replies(thread_replies) -%}
-{% trans count=thread_replies, replies=('<strong>' ~ (thread_replies|intcomma) ~ '</strong>')|safe -%}
+{% trans count=thread_replies, replies=thread_replies|intcomma -%}
 {{ replies }} reply
 {%- pluralize -%}
 {{ replies }} replies

+ 66 - 49
templates/cranefly/popular_threads.html

@@ -14,56 +14,73 @@
 <div class="container container-primary">
   {% if threads %}
   <div class="forum-threads-list">
-    <table class="table">
-      <thead>
-        <tr>
-          <th>{% trans %}Thread{% endtrans %}</th>
-          <th class="span1">{% trans %}Rating{% endtrans %}</th>
-          <th class="span5">{% trans %}Activity{% endtrans %}</th>
-          {% if user.is_authenticated() and list_form %}
-          <th class="check-cell"><label class="checkbox"><input type="checkbox" class="checkbox-master"></label></th>
+    <div class="header">
+      <div class="row-fluid">
+        <div class="span7">{% trans %}Thread{% endtrans %}</div>
+        <div class="span5 thread-activity">
+          <div class="thread-replies">{% trans %}Replies{% endtrans %}</div>
+          <div class="thread-last">{% trans %}Last Reply{% endtrans %}</div>
+        </div>
+      </div>
+    </div>
+    {% for thread in threads %}
+    <div class="thread-row{% if thread.pk == 2 or not thread.is_read %} thread-new{% endif %}{% if loop.last %} thread-last{% endif %}">
+      <div class="row-fluid">
+        <div class="span7">
+          {% if thread.is_read and not thread.pk == 2 %}
+          <a href="{% url 'thread_new' thread=thread.pk, slug=thread.slug %}" class="thread-icon thread-icon-last tooltip-top" title="{% trans %}Click to see last post{% endtrans %}"><i class="icon-asterisk"></i></a>
+          {% else %}
+          <a href="{% url 'thread_new' thread=thread.pk, slug=thread.slug %}" class="thread-icon thread-icon-new tooltip-top" title="{% trans %}Click to see first unread post{% endtrans %}"><i class="icon-fire"></i></a>
           {% endif %}
-        </tr>
-      </thead>
-      <tbody>
-        {% for thread in threads %}
-        <tr>
-          <td>
-            <a href="{% url 'thread_new' thread=thread.pk, slug=thread.slug %}" class="thread-icon{% if not thread.is_read %} thread-new{% endif %} tooltip-top" title="{% if not thread.is_read -%}
-            {% trans %}Click to see first unread post{% endtrans %}
-            {%- else -%}
-            {% trans %}Click to see last post{% endtrans %}
-            {%- endif %}"><i class="icon-comment"></i></a>
-            <a href="{% url 'thread' thread=thread.pk, slug=thread.slug %}" class="thread-name">{{ thread.name }}</a>
-            <span class="thread-details">
-              {% trans user=thread_starter(thread), forum=thread_forum(thread), start=thread.start|reltimesince|low %}by {{ user }} in {{ forum }} {{ start }}{% endtrans %}
-            </span>
-            <ul class="unstyled thread-flags">
-              {% if thread.weight == 2 %}
-              <li><i class="icon-star tooltip-top" title="{% trans %}This thread is an annoucement{% endtrans %}"></i></li>
-              {% endif %}
-              {% if thread.weight == 1 %}
-              <li><i class="icon-star-empty tooltip-top" title="{% trans %}This thread is sticky{% endtrans %}"></i></li>
-              {% endif %}
-              {% if thread.closed %}
-              <li><i class="icon-lock tooltip-top" title="{% trans %}This thread is closed{% endtrans %}"></i></li>
+
+          <a href="{% url 'thread' thread=thread.pk, slug=thread.slug %}" class="thread-name">{{ thread.name }}</a>
+          <span class="thread-details">
+            {% trans user=thread_starter(thread), forum=thread_forum(thread) %}by {{ user }} in {{ forum }}{% endtrans %}
+          </span>
+
+          <ul class="unstyled thread-flags">
+            {% if thread.replies_reported %}
+            <li><i class="icon-warning-sign tooltip-top" title="{% trans %}This thread has reported replies{% endtrans %}"></i></li>
+            {% endif %}
+            {% if thread.replies_moderated %}
+            <li><i class="icon-question-sign tooltip-top" title="{% trans %}This thread has unreviewed replies{% endtrans %}"></i></li>
+            {% endif %}
+            {% if thread.weight == 2 %}
+            <li><i class="icon-star tooltip-top" title="{% trans %}This thread is an annoucement{% endtrans %}"></i></li>
+            {% endif %}
+            {% if thread.weight == 1 %}
+            <li><i class="icon-star-empty tooltip-top" title="{% trans %}This thread is sticky{% endtrans %}"></i></li>
+            {% endif %}
+            {% if thread.moderated  %}
+            <li><i class="icon-eye-close tooltip-top" title="{% trans %}This thread awaits review{% endtrans %}"></i></li>
+            {% endif %}
+            {% if thread.deleted %}
+            <li><i class="icon-trash tooltip-top" title="{% trans %}This thread is deleted{% endtrans %}"></i></li>
+            {% endif %}
+            {% if thread.closed %}
+            <li><i class="icon-lock tooltip-top" title="{% trans %}This thread is closed{% endtrans %}"></i></li>
+            {% endif %}
+          </ul>
+        </div>
+        <div class="span5 thread-activity">
+          <div class="thread-replies tooltip-top" title="{{ replies(thread.replies) }}">{{ thread.replies|intcomma }} <i class="icon-comment"></i></div>
+
+          <div class="thread-last-reply">
+            {% if settings.avatars_on_threads_list %}
+            <span class="thread-last-avatar">
+              {% if thread.last_poster_id %}
+              <a href="{% url 'user' user=thread.last_poster.pk, username=thread.last_poster.username_slug %}"><img src="{{ thread.last_poster.get_avatar(30) }}" alt=""></a>
+              {% else %}
+              <img src="{{ macros.avatar_guest(40) }}" alt="" class="user-avatar">
               {% endif %}
-            </ul>
-          </td>
-          <td>
-            <div class="thread-rating{% if (thread.upvotes-thread.downvotes) > 0 %} thread-rating-positive{% elif (thread.upvotes-thread.downvotes) < 0 %} thread-rating-negative{% endif %}">
-              {% if (thread.upvotes-thread.downvotes) > 0 %}+{% elif (thread.upvotes-thread.downvotes) < 0 %}-{% endif %}{{ (thread.upvotes-thread.downvotes)|abs|intcomma }}
-            </div>
-          </td>
-          <td>
-            <div class="thread-last-reply">
-              {{ replies(thread.replies) }} - {% trans user=thread_reply(thread), last=thread.last|reltimesince|low %}last by {{ user }} {{ last }}{% endtrans %}
-            </div>
-          </td>
-        </tr>
-        {% endfor %}
-      </tbody>
-    </table>
+            </span>
+            {% endif %}
+            {{ thread_reply(thread) }}, {{ thread.last|reldate|low }}
+          </div>
+        </div>
+      </div>
+    </div>
+    {% endfor %}
   </div>
   {% else %}
   <p class="lead">{% trans %}Looks like there are no popular threads... yet!{% endtrans %}</p>
@@ -73,7 +90,7 @@
 
 
 {% macro replies(thread_replies) -%}
-{% trans count=thread_replies, replies=('<strong>' ~ (thread_replies|intcomma) ~ '</strong>')|safe -%}
+{% trans count=thread_replies, replies=thread_replies|intcomma -%}
 {{ replies }} reply
 {%- pluralize -%}
 {{ replies }} replies

+ 77 - 73
templates/cranefly/private_threads/list.html

@@ -35,83 +35,87 @@
   </div>
 
   <div class="forum-threads-list">
-    <table class="table">
-      <thead>
-        <tr>
-          <th>{% trans %}Thread{% endtrans %}</th>
-          <th class="span1">{% trans %}Rating{% endtrans %}</th>
-          <th class="span5">{% trans %}Activity{% endtrans %}</th>
+    <div class="header">
+      <div class="row-fluid">
+        <div class="span7">{% trans %}Thread{% endtrans %}</div>
+        <div class="span5 thread-activity">
+          <div class="thread-replies">{% trans %}Replies{% endtrans %}</div>
+          <div class="thread-last">{% trans %}Last Reply{% endtrans %}</div>
           {% if list_form %}
-          <th class="check-cell"><label class="checkbox"><input type="checkbox" class="checkbox-master"></label></th>
+          <div class="pull-right check-cell">
+            <label class="checkbox"><input type="checkbox" class="checkbox-master"></label>
+          </div>
           {% endif %}
-        </tr>
-      </thead>
-      <tbody>
-        {% for thread in threads %}
-        <tr>
-          <td>
-            <a href="{% url 'private_thread_new' thread=thread.pk, slug=thread.slug %}" class="thread-icon{% if not thread.is_read %} thread-new{% endif %} tooltip-top" title="{% if not thread.is_read -%}
-            {% trans %}Click to see first unread post{% endtrans %}
-            {%- else -%}
-            {% trans %}Click to see last post{% endtrans %}
-            {%- endif %}"><i class="icon-comment"></i></a>
-            <a href="{% url 'private_thread' thread=thread.pk, slug=thread.slug %}" class="thread-name">{{ thread.name }}</a>
-            <span class="thread-details">
-              {% trans user=thread_starter(thread), start=thread.start|reltimesince|low %}by {{ user }} {{ start }}{% endtrans %}
-            </span>
-            <ul class="unstyled thread-flags">
-              {% if thread.replies_reported %}
-              <li><i class="icon-warning-sign tooltip-top" title="{% trans %}This thread has reported replies{% endtrans %}"></i></li>
-              {% endif %}
-              {% if thread.replies_moderated %}
-              <li><i class="icon-question-sign tooltip-top" title="{% trans %}This thread has unreviewed replies{% endtrans %}"></i></li>
-              {% endif %}
-              {% if thread.weight == 2 %}
-              <li><i class="icon-star tooltip-top" title="{% trans %}This thread is an annoucement{% endtrans %}"></i></li>
-              {% endif %}
-              {% if thread.weight == 1 %}
-              <li><i class="icon-star-empty tooltip-top" title="{% trans %}This thread is sticky{% endtrans %}"></i></li>
-              {% endif %}
-              {% if thread.moderated  %}
-              <li><i class="icon-eye-close tooltip-top" title="{% trans %}This thread awaits review{% endtrans %}"></i></li>
-              {% endif %}
-              {% if thread.deleted %}
-              <li><i class="icon-trash tooltip-top" title="{% trans %}This thread is deleted{% endtrans %}"></i></li>
-              {% endif %}
-              {% if thread.closed %}
-              <li><i class="icon-lock tooltip-top" title="{% trans %}This thread is closed{% endtrans %}"></i></li>
+        </div>
+      </div>
+    </div>
+    {% for thread in threads %}
+    <div class="thread-row{% if thread.pk == 2 or not thread.is_read %} thread-new{% endif %}{% if loop.last %} thread-last{% endif %}">
+      <div class="row-fluid">
+        <div class="span7">
+          {% if thread.is_read and not thread.pk == 2 %}
+          <a href="{% url 'thread_new' thread=thread.pk, slug=thread.slug %}" class="thread-icon thread-icon-last tooltip-top" title="{% trans %}Click to see last post{% endtrans %}"><i class="icon-asterisk"></i></a>
+          {% else %}
+          <a href="{% url 'thread_new' thread=thread.pk, slug=thread.slug %}" class="thread-icon thread-icon-new tooltip-top" title="{% trans %}Click to see first unread post{% endtrans %}"><i class="icon-fire"></i></a>
+          {% endif %}
+
+          <a href="{% url 'thread' thread=thread.pk, slug=thread.slug %}" class="thread-name">{{ thread.name }}</a>
+          <span class="thread-details">
+            {% trans user=thread_starter(thread), start=thread.start|reldate|low %}by {{ user }}, {{ start }}{% endtrans %}
+          </span>
+
+          <ul class="unstyled thread-flags">
+            {% if thread.replies_reported %}
+            <li><i class="icon-warning-sign tooltip-top" title="{% trans %}This thread has reported replies{% endtrans %}"></i></li>
+            {% endif %}
+            {% if thread.replies_moderated %}
+            <li><i class="icon-question-sign tooltip-top" title="{% trans %}This thread has unreviewed replies{% endtrans %}"></i></li>
+            {% endif %}
+            {% if thread.weight == 2 %}
+            <li><i class="icon-star tooltip-top" title="{% trans %}This thread is an annoucement{% endtrans %}"></i></li>
+            {% endif %}
+            {% if thread.weight == 1 %}
+            <li><i class="icon-star-empty tooltip-top" title="{% trans %}This thread is sticky{% endtrans %}"></i></li>
+            {% endif %}
+            {% if thread.moderated  %}
+            <li><i class="icon-eye-close tooltip-top" title="{% trans %}This thread awaits review{% endtrans %}"></i></li>
+            {% endif %}
+            {% if thread.deleted %}
+            <li><i class="icon-trash tooltip-top" title="{% trans %}This thread is deleted{% endtrans %}"></i></li>
+            {% endif %}
+            {% if thread.closed %}
+            <li><i class="icon-lock tooltip-top" title="{% trans %}This thread is closed{% endtrans %}"></i></li>
+            {% endif %}
+          </ul>
+        </div>
+        <div class="span5 thread-activity">
+          <div class="thread-replies tooltip-top" title="{{ replies(thread.replies) }}">{{ thread.replies|intcomma }} <i class="icon-comment"></i></div>
+
+          <div class="thread-last-reply">
+            {% if settings.avatars_on_threads_list %}
+            <span class="thread-last-avatar">
+              {% if thread.last_poster_id %}
+              <a href="{% url 'user' user=thread.last_poster.pk, username=thread.last_poster.username_slug %}"><img src="{{ thread.last_poster.get_avatar(30) }}" alt=""></a>
+              {% else %}
+              <img src="{{ macros.avatar_guest(40) }}" alt="" class="user-avatar">
               {% endif %}
-            </ul>
-          </td>
-          <td>
-            <div class="thread-rating{% if (thread.upvotes-thread.downvotes) > 0 %} thread-rating-positive{% elif (thread.upvotes-thread.downvotes) < 0 %} thread-rating-negative{% endif %}">
-              {% if (thread.upvotes-thread.downvotes) > 0 %}+{% elif (thread.upvotes-thread.downvotes) < 0 %}-{% endif %}{{ (thread.upvotes-thread.downvotes)|abs|intcomma }}
-            </div>
-          </td>
-          <td>
-            <div class="thread-last-reply">
-              {{ replies(thread.replies) }} - {% trans user=thread_reply(thread), last=thread.last|reltimesince|low %}last by {{ user }} {{ last }}{% endtrans %}
-            </div>
-          </td>
+            </span>
+            {% endif %}
+            {{ thread_reply(thread) }}, {{ thread.last|reldate|low }}
+          </div>
+
           {% if list_form %}
-          <td class="check-cell">{% if thread.forum_id == forum.pk %}<label class="checkbox"><input form="threads_form" name="{{ list_form['list_items']['html_name'] }}" type="checkbox" class="checkbox-member" value="{{ thread.pk }}"{% if list_form['list_items']['has_value'] and ('' ~ thread.pk) in list_form['list_items']['value'] %} checked="checked"{% endif %}></label>{% else %}&nbsp;{% endif %}</td>
+          <label class="thread-select checkbox"><input form="threads_form" name="{{ list_form['list_items']['html_name'] }}" type="checkbox" class="checkbox-member" value="{{ thread.pk }}"{% if list_form['list_items']['has_value'] and ('' ~ thread.pk) in list_form['list_items']['value'] %} checked="checked"{% endif %}></label>
           {% endif %}
-        </tr>
-        {% else %}
-        <tr>
-          <td colspan="4" class="threads-list-empty">
-            {% if tab == 'all' %}
-            {% trans %}You are not participating in any private discussions.{% endtrans %}
-            {% elif tab == 'new' %}
-            {% trans %}There are no unread private threads.{% endtrans %}
-            {% else %}
-            {% trans %}You have started no private threads.{% endtrans %}
-            {% endif %}
-          </td>
-        </tr>
-        {% endfor %}
-      </tbody>
-    </table>
+        </div>
+      </div>
+    </div>
+    {% else %}
+    <div class="thread-row threads-list-empty">
+      {% trans %}You are not participating in any private discussions.{% endtrans %}
+    </div>
+    {% endfor %}
+    
     {% if list_form %}
     <div class="threads-actions">
       <form id="threads_form" class="form-inline pull-right" action="{{ request_path }}" method="POST">
@@ -135,7 +139,7 @@
 
 
 {% macro replies(thread_replies) -%}
-{% trans count=thread_replies, replies=('<strong>' ~ (thread_replies|intcomma) ~ '</strong>')|safe -%}
+{% trans count=thread_replies, replies=thread_replies|intcomma -%}
 {{ replies }} reply
 {%- pluralize -%}
 {{ replies }} replies

+ 78 - 68
templates/cranefly/threads/list.html

@@ -112,77 +112,87 @@
   </div>
 
   <div class="forum-threads-list">
-    <table class="table">
-      <thead>
-        <tr>
-          <th>{% trans %}Thread{% endtrans %}</th>
-          <th class="span1">{% trans %}Rating{% endtrans %}</th>
-          <th class="span5">{% trans %}Activity{% endtrans %}</th>
+    <div class="header">
+      <div class="row-fluid">
+        <div class="span7">{% trans %}Thread{% endtrans %}</div>
+        <div class="span5 thread-activity">
+          <div class="thread-replies">{% trans %}Replies{% endtrans %}</div>
+          <div class="thread-last">{% trans %}Last Reply{% endtrans %}</div>
           {% if user.is_authenticated() and list_form %}
-          <th class="check-cell"><label class="checkbox"><input type="checkbox" class="checkbox-master"></label></th>
+          <div class="pull-right check-cell">
+            <label class="checkbox"><input type="checkbox" class="checkbox-master"></label>
+          </div>
           {% endif %}
-        </tr>
-      </thead>
-      <tbody>
-        {% for thread in threads %}
-        <tr>
-          <td>
-            <a href="{% url 'thread_new' thread=thread.pk, slug=thread.slug %}" class="thread-icon{% if not thread.is_read %} thread-new{% endif %} tooltip-top" title="{% if not thread.is_read -%}
-            {% trans %}Click to see first unread post{% endtrans %}
-            {%- else -%}
-            {% trans %}Click to see last post{% endtrans %}
-            {%- endif %}"><i class="icon-comment"></i></a>
-            <a href="{% url 'thread' thread=thread.pk, slug=thread.slug %}" class="thread-name">{{ thread.name }}</a>
-            <span class="thread-details">
-              {% trans user=thread_starter(thread), start=thread.start|reltimesince|low %}by {{ user }} {{ start }}{% endtrans %}
-            </span>
-            <ul class="unstyled thread-flags">
-              {% if thread.replies_reported %}
-              <li><i class="icon-warning-sign tooltip-top" title="{% trans %}This thread has reported replies{% endtrans %}"></i></li>
-              {% endif %}
-              {% if thread.replies_moderated %}
-              <li><i class="icon-question-sign tooltip-top" title="{% trans %}This thread has unreviewed replies{% endtrans %}"></i></li>
-              {% endif %}
-              {% if thread.weight == 2 %}
-              <li><i class="icon-star tooltip-top" title="{% trans %}This thread is an annoucement{% endtrans %}"></i></li>
-              {% endif %}
-              {% if thread.weight == 1 %}
-              <li><i class="icon-star-empty tooltip-top" title="{% trans %}This thread is sticky{% endtrans %}"></i></li>
-              {% endif %}
-              {% if thread.moderated  %}
-              <li><i class="icon-eye-close tooltip-top" title="{% trans %}This thread awaits review{% endtrans %}"></i></li>
-              {% endif %}
-              {% if thread.deleted %}
-              <li><i class="icon-trash tooltip-top" title="{% trans %}This thread is deleted{% endtrans %}"></i></li>
-              {% endif %}
-              {% if thread.closed %}
-              <li><i class="icon-lock tooltip-top" title="{% trans %}This thread is closed{% endtrans %}"></i></li>
+        </div>
+      </div>
+    </div>
+    {% for thread in threads %}
+    <div class="thread-row{% if thread.pk == 2 or not thread.is_read %} thread-new{% endif %}{% if loop.last %} thread-last{% endif %}">
+      <div class="row-fluid">
+        <div class="span7">
+          {% if thread.is_read and not thread.pk == 2 %}
+          <a href="{% url 'thread_new' thread=thread.pk, slug=thread.slug %}" class="thread-icon thread-icon-last tooltip-top" title="{% trans %}Click to see last post{% endtrans %}"><i class="icon-asterisk"></i></a>
+          {% else %}
+          <a href="{% url 'thread_new' thread=thread.pk, slug=thread.slug %}" class="thread-icon thread-icon-new tooltip-top" title="{% trans %}Click to see first unread post{% endtrans %}"><i class="icon-fire"></i></a>
+          {% endif %}
+
+          <a href="{% url 'thread' thread=thread.pk, slug=thread.slug %}" class="thread-name">{{ thread.name }}</a>
+          <span class="thread-details">
+            {% trans user=thread_starter(thread), start=thread.start|reldate|low %}by {{ user }}, {{ start }}{% endtrans %}
+          </span>
+
+          <ul class="unstyled thread-flags">
+            {% if thread.replies_reported %}
+            <li><i class="icon-warning-sign tooltip-top" title="{% trans %}This thread has reported replies{% endtrans %}"></i></li>
+            {% endif %}
+            {% if thread.replies_moderated %}
+            <li><i class="icon-question-sign tooltip-top" title="{% trans %}This thread has unreviewed replies{% endtrans %}"></i></li>
+            {% endif %}
+            {% if thread.weight == 2 %}
+            <li><i class="icon-star tooltip-top" title="{% trans %}This thread is an annoucement{% endtrans %}"></i></li>
+            {% endif %}
+            {% if thread.weight == 1 %}
+            <li><i class="icon-star-empty tooltip-top" title="{% trans %}This thread is sticky{% endtrans %}"></i></li>
+            {% endif %}
+            {% if thread.moderated  %}
+            <li><i class="icon-eye-close tooltip-top" title="{% trans %}This thread awaits review{% endtrans %}"></i></li>
+            {% endif %}
+            {% if thread.deleted %}
+            <li><i class="icon-trash tooltip-top" title="{% trans %}This thread is deleted{% endtrans %}"></i></li>
+            {% endif %}
+            {% if thread.closed %}
+            <li><i class="icon-lock tooltip-top" title="{% trans %}This thread is closed{% endtrans %}"></i></li>
+            {% endif %}
+          </ul>
+        </div>
+        <div class="span5 thread-activity">
+          <div class="thread-replies tooltip-top" title="{{ replies(thread.replies) }}">{{ thread.replies|intcomma }} <i class="icon-comment"></i></div>
+
+          <div class="thread-last-reply">
+            {% if settings.avatars_on_threads_list %}
+            <span class="thread-last-avatar">
+              {% if thread.last_poster_id %}
+              <a href="{% url 'user' user=thread.last_poster.pk, username=thread.last_poster.username_slug %}"><img src="{{ thread.last_poster.get_avatar(30) }}" alt=""></a>
+              {% else %}
+              <img src="{{ macros.avatar_guest(40) }}" alt="" class="user-avatar">
               {% endif %}
-            </ul>
-          </td>
-          <td>
-            <div class="thread-rating{% if (thread.upvotes-thread.downvotes) > 0 %} thread-rating-positive{% elif (thread.upvotes-thread.downvotes) < 0 %} thread-rating-negative{% endif %}">
-              {% if (thread.upvotes-thread.downvotes) > 0 %}+{% elif (thread.upvotes-thread.downvotes) < 0 %}-{% endif %}{{ (thread.upvotes-thread.downvotes)|abs|intcomma }}
-            </div>
-          </td>
-          <td>
-            <div class="thread-last-reply">
-              {{ replies(thread.replies) }} - {% trans user=thread_reply(thread), last=thread.last|reltimesince|low %}last by {{ user }} {{ last }}{% endtrans %}
-            </div>
-          </td>
+            </span>
+            {% endif %}
+            {{ thread_reply(thread) }}, {{ thread.last|reldate|low }}
+          </div>
+
           {% if user.is_authenticated() and list_form %}
-          <td class="check-cell">{% if thread.forum_id == forum.pk %}<label class="checkbox"><input form="threads_form" name="{{ list_form['list_items']['html_name'] }}" type="checkbox" class="checkbox-member" value="{{ thread.pk }}"{% if list_form['list_items']['has_value'] and ('' ~ thread.pk) in list_form['list_items']['value'] %} checked="checked"{% endif %}></label>{% else %}&nbsp;{% endif %}</td>
+          <label class="thread-select checkbox"><input form="threads_form" name="{{ list_form['list_items']['html_name'] }}" type="checkbox" class="checkbox-member" value="{{ thread.pk }}"{% if list_form['list_items']['has_value'] and ('' ~ thread.pk) in list_form['list_items']['value'] %} checked="checked"{% endif %}></label>
           {% endif %}
-        </tr>
-        {% else %}
-        <tr>
-          <td colspan="4" class="threads-list-empty">
-            {% trans %}There are no threads in this forum.{% endtrans %}
-          </td>
-        </tr>
-        {% endfor %}
-      </tbody>
-    </table>
+        </div>
+      </div>
+    </div>
+    {% else %}
+    <div class="thread-row threads-list-empty">
+      {% trans %}There are no threads in this forum.{% endtrans %}
+    </div>
+    {% endfor %}
+
     {% if user.is_authenticated() and list_form %}
     <div class="threads-actions">
       <form id="threads_form" class="form-inline pull-right" action="{{ request_path }}" method="POST">
@@ -240,7 +250,7 @@
 {%- endmacro %}
 
 {% macro replies(thread_replies) -%}
-{% trans count=thread_replies, replies=('<strong>' ~ (thread_replies|intcomma) ~ '</strong>')|safe -%}
+{% trans count=thread_replies, replies=thread_replies|intcomma -%}
 {{ replies }} reply
 {%- pluralize -%}
 {{ replies }} replies
@@ -284,7 +294,7 @@
       {% endfor %}
       {%- if user.is_authenticated() and list_form %}
       $('#threads_form').submit(function() {
-        if ($('.check-cell[]:checked').length == 0) {
+        if ($('.thread-select[]:checked').length == 0) {
           alert("{% trans %}You have to select at least one thread.{% endtrans %}");
           return false;
         }

+ 58 - 4
templates/cranefly/watched.html

@@ -24,9 +24,63 @@
   {% endif %}
 
   {% if threads %}
+  {{ pager() }}
   <div class="forum-threads-list watched-threads">
-    {{ pager() }}
-    <table class="table">
+    <div class="header">
+      <div class="row-fluid">
+        <div class="span7">{% trans %}Thread{% endtrans %}</div>
+        <div class="span5 thread-activity">
+          <div class="thread-last">{% trans %}Last Reply{% endtrans %}</div>
+        </div>
+      </div>
+    </div>
+    {% for thread in threads %}
+    <div id="watch-{{ loop.index }}" class="thread-row{% if thread.pk == 2 or not thread.is_read %} thread-new{% endif %}{% if loop.last %} thread-last{% endif %}">
+      <div class="row-fluid">
+        <div class="span7">
+          {% if thread.is_read and not thread.pk == 2 %}
+          <a href="{% url 'thread_new' thread=thread.pk, slug=thread.slug %}" class="thread-icon thread-icon-last tooltip-top" title="{% trans %}Click to see last post{% endtrans %}"><i class="icon-asterisk"></i></a>
+          {% else %}
+          <a href="{% url 'thread_new' thread=thread.pk, slug=thread.slug %}" class="thread-icon thread-icon-new tooltip-top" title="{% trans %}Click to see first unread post{% endtrans %}"><i class="icon-fire"></i></a>
+          {% endif %}
+
+          <a href="{% url 'thread' thread=thread.pk, slug=thread.slug %}" class="thread-name">{{ thread.name }}</a>
+          <span class="thread-details">
+            {% trans user=thread_starter(thread), forum=thread_forum(thread) %}by {{ user }} in {{ forum }}{% endtrans %}
+          </span>
+        </div>
+        <div class="span5 thread-activity">
+          <div class="thread-last-reply">
+            {% if settings.avatars_on_threads_list %}
+            <span class="thread-last-avatar">
+              {% if thread.last_poster_id %}
+              <a href="{% url 'user' user=thread.last_poster.pk, username=thread.last_poster.username_slug %}"><img src="{{ thread.last_poster.get_avatar(30) }}" alt=""></a>
+              {% else %}
+              <img src="{{ macros.avatar_guest(40) }}" alt="" class="user-avatar">
+              {% endif %}
+            </span>
+            {% endif %}
+            {{ thread_reply(thread) }}, {{ thread.last|reldate|low }}
+          </div>
+
+          <div class="thread-options">
+            <form action="{% if thread.send_email %}{{ thread_url(thread, 'unwatch_email') }}{% else %}{{ thread_url(thread, 'watch_email') }}{% endif %}" method="post">
+              <input type="hidden" name="{{ csrf_id }}" value="{{ csrf_token }}">
+              <input type="hidden" name="retreat" value="{{ request_path }}#watch-{{ loop.index }}">
+              <button type="submit" class="btn btn-{% if thread.send_email %}success{% else %}inverse{% endif %} tooltip-top" title="{% if thread.send_email %}{% trans %}Don't notify with e-mail{% endtrans %}{% else %}{% trans %}Notify with e-mail{% endtrans %}{% endif %}"><i class="icon-envelope"></i></button>
+            </form>
+
+            <form action="{{ thread_url(thread, 'unwatch') }}" method="post">
+              <input type="hidden" name="{{ csrf_id }}" value="{{ csrf_token }}">
+              <input type="hidden" name="retreat" value="{{ delete_retreat(loop) }}">
+              <button type="submit" class="btn btn-danger tooltip-top" title="{% trans %}Unwatch{% endtrans %}"><i class="icon-remove"></i></button>
+            </form>
+          </div>
+        </div>
+      </div>
+    </div>
+    {% endfor %}
+    {#<table class="table">
       <thead>
         <tr>
           <th>{% trans %}Thread{% endtrans %}</th>
@@ -68,9 +122,9 @@
         </tr>
         {% endfor %}
       </tbody>
-    </table>
-    {{ pager() }}
+    </table>#}
   </div>
+  {{ pager() }}
   {% else %}
   <p class="lead">{% if new -%}
     {% trans %}There are no unread threads that you are watching.{% endtrans %}