Просмотр исходного кода

further auth progress, responsive navbar and footer

Rafał Pitoń 10 лет назад
Родитель
Сommit
7274fbe441
31 измененных файлов с 1000 добавлено и 157 удалено
  1. 13 1
      docs/developers/settings.rst
  2. 21 0
      misago/core/migrations/0002_basic_settings.py
  3. 3 0
      misago/emberapp/app/components/forum-footer.js
  4. 23 0
      misago/emberapp/app/components/forum-navbar.js
  5. 18 6
      misago/emberapp/app/components/user-avatar.js
  6. 2 1
      misago/emberapp/app/components/user-nav.js
  7. 0 21
      misago/emberapp/app/controllers/index.js
  8. 63 5
      misago/emberapp/app/styles/misago/buttons.less
  9. 64 0
      misago/emberapp/app/styles/misago/dropdowns.less
  10. 1 3
      misago/emberapp/app/styles/misago/footer.less
  11. 2 0
      misago/emberapp/app/styles/misago/misago.less
  12. 41 0
      misago/emberapp/app/styles/misago/misc.less
  13. 187 18
      misago/emberapp/app/styles/misago/navbar.less
  14. 60 5
      misago/emberapp/app/styles/misago/variables.less
  15. 2 1
      misago/emberapp/app/templates/application.hbs
  16. 1 1
      misago/emberapp/app/templates/components/forms/login-form.hbs
  17. 30 32
      misago/emberapp/app/templates/components/forum-footer.hbs
  18. 153 0
      misago/emberapp/app/templates/components/forum-navbar.hbs
  19. 83 4
      misago/emberapp/app/templates/components/user-nav.hbs
  20. 30 10
      misago/emberapp/app/templates/index.hbs
  21. 145 16
      misago/emberapp/app/templates/navbar.hbs
  22. BIN
      misago/emberapp/public/misago/img/misago_logo.png
  23. BIN
      misago/emberapp/public/misago/img/site-icon.png
  24. BIN
      misago/emberapp/public/misago/img/site-logo.png
  25. 11 11
      misago/emberapp/tests/acceptance/error-toast-test.js
  26. 13 13
      misago/emberapp/tests/acceptance/login-test.js
  27. 8 8
      misago/emberapp/tests/acceptance/registration-test.js
  28. 1 1
      misago/emberapp/vendor/testutils/misago-preload-data.js
  29. 1 0
      misago/users/serializers/__init__.py
  30. 19 0
      misago/users/serializers/rank.py
  31. 5 0
      misago/users/serializers/user.py

+ 13 - 1
docs/developers/settings.rst

@@ -135,10 +135,22 @@ default_timezone
 Default timezone used by guests and newly registered users that haven't changed their timezone prefferences.
 
 
+forum_branding_display
+----------------------
+
+Controls branding's visibility in forum navbar.
+
+
+forum_branding_text
+-------------------
+
+Allows you to include text besides brand logo on your forum.
+
+
 forum_name
 ----------
 
-Forum name, displayed in default templates forum navbar and in titles of pages.
+Forum name, displayed in titles of pages.
 
 
 forum_index_meta_description

+ 21 - 0
misago/core/migrations/0002_basic_settings.py

@@ -48,6 +48,27 @@ def create_basic_settings_group(apps, schema_editor):
                     },
                 },
                 {
+                    'setting': 'forum_branding_display',
+                    'name': _("Display branding"),
+                    'description': _("Switch branding in forum's navbar."),
+                    'legend': _("Branding"),
+                    'value': True,
+                    'python_type': 'bool',
+                    'form_field': 'yesno',
+                    'is_public': True,
+                },
+                {
+                    'setting': 'forum_branding_text',
+                    'name': _("Branding text"),
+                    'description': _("Optional text displayed besides "
+                                     "brand image in navbar."),
+                    'value': "isago",
+                    'field_extra': {
+                        'max_length': 255
+                    },
+                    'is_public': True,
+                },
+                {
                     'setting': 'email_footer',
                     'name': _("E-mails footer"),
                     'description': _("Optional short message included "

+ 3 - 0
misago/emberapp/app/components/forum-footer.js

@@ -1,6 +1,9 @@
 import Ember from 'ember';
 
 export default Ember.Component.extend({
+  tagName: 'footer',
+  classNames: 'site-footer',
+
   showTermsLink: function() {
     return this.get('settings.terms_of_service') || this.get('settings.terms_of_service_link');
   }.property('settings'),

+ 23 - 0
misago/emberapp/app/components/forum-navbar.js

@@ -0,0 +1,23 @@
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+  classNames: 'navbar-spacer',
+
+  affixNavbar: function() {
+    // take navbar's height in document
+    this.$().height(this.$().height());
+
+    // affix navbar
+    this.$('.navbar').affix({
+      offset: {
+        top: this.$('.navbar').offset().top
+      }
+    });
+  }.on('didInsertElement'),
+
+  actions: {
+    showModal: function(template, model) {
+      this.modal.show(template, model);
+    }
+  }
+});

+ 18 - 6
misago/emberapp/app/components/user-avatar.js

@@ -3,15 +3,27 @@ import Ember from 'ember';
 export default Ember.Component.extend({
   tagName: 'img',
   classNames: 'user-avatar',
-  attributeBindings: ['src', 'alt'],
+  attributeBindings: ['src', 'alt', 'size:width', 'size:height'],
 
   size: 100,
 
   src: function() {
-    return '/user-avatar/' + this.get('size') + '/' + this.get('id') + '.png';
-  }.property('id', 'size'),
+    var src = Ember.$('base').attr('href') + 'user-avatar/';
 
-  alt: function() {
-    return '';
-  }.property()
+    if (this.get('user')) {
+      if (this.get('prefix') && this.get('token')) {
+        // special avatar source
+        src += this.get('prefix') + ':' + this.get('token') + '/';
+      } else {
+        // just avatar size
+        src += this.get('size') + '/';
+      }
+      return src + this.get('user') + '.png';
+    } else {
+      // just append avatar size to file to produce no-avatar placeholder
+      return src + this.get('size') + '.png';
+    }
+  }.property('user', 'size'),
+
+  alt: ''
 });

+ 2 - 1
misago/emberapp/app/components/user-nav.js

@@ -1,7 +1,8 @@
 import Ember from 'ember';
 
 export default Ember.Component.extend({
-  classNames: ['user-nav', 'navbar-right'],
+  tagName: 'li',
+  classNames: ['user-menu', 'dropdown'],
 
   actions: {
     logout: function() {

+ 0 - 21
misago/emberapp/app/controllers/index.js

@@ -1,21 +0,0 @@
-import Ember from 'ember';
-
-export default Ember.Controller.extend({
-  actions: {
-    testInfo: function() {
-      this.toast.info(this.get('newFlash'));
-    },
-
-    testSuccess: function() {
-      this.toast.success(this.get('newFlash'));
-    },
-
-    testWarning: function() {
-      this.toast.warning(this.get('newFlash'));
-    },
-
-    testError: function() {
-      this.toast.error(this.get('newFlash'));
-    }
-  }
-});

+ 63 - 5
misago/emberapp/app/styles/misago/buttons.less

@@ -2,9 +2,43 @@
 // Buttons
 // --------------------------------------------------
 
+// Mixin for styles
+.btn-outlined-style(@border, @bg, @color) {
+  &, &:visited {
+    background-color: transparent;
+    border-color: @border;
 
-// Double border size on default and lg buttons
-.btn {
+    color: @border;
+  }
+
+  &:hover, &:focus {
+    background-color: fadeOut(@bg, 60%);
+    border-color: @border;
+
+    color: @color;
+  }
+
+  &:active {
+    background-color: darken(@bg, 10%);
+    border-color: @border;
+    .box-shadow(none);
+
+    color: @color;
+  }
+
+  &.disabled {
+    &, &:visited, &:hover, &:focus, &:active {
+      background-color: transparent;
+      border-color: desaturate(@border, 50%);
+
+      color: desaturate(@border, 50%);
+    }
+  }
+}
+
+
+// Outlined button
+.btn-outlined {
   border-width: 2px;
 
   .button-size(@padding-base-vertical - 1; @padding-base-horizontal; @font-size-base; @line-height-base; @border-radius-base);
@@ -22,11 +56,35 @@
     border-width: 1px;
     .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @border-radius-small);
   }
-}
 
+  // Outline varieties for buttons
+  &.btn-default, &.btn-primary, &.btn-success, &.btn-info, &.btn-warning, &.btn-danger {
+    &, &:visited {
+      background-color: transparent;
+    }
+  }
+
+  &.btn-primary {
+    .btn-outlined-style(@btn-primary-border, @btn-primary-bg, @btn-primary-color);
+  }
+
+  &.btn-success {
+    .btn-outlined-style(@btn-success-border, @btn-success-bg, @btn-success-color);
+  }
+
+  &.btn-info {
+    .btn-outlined-style(@btn-info-border, @btn-info-bg, @btn-info-color);
+  }
+
+  &.btn-warning {
+    .btn-outlined-style(@btn-warning-border, @btn-warning-bg, @btn-warning-color);
+  }
+
+  &.btn-danger {
+    .btn-outlined-style(@btn-danger-border, @btn-danger-bg, @btn-danger-color);
+  }
 
-// Extra states for default btn
-.btn {
+  // Extra states for default btn
   &.btn-default {
     &:hover,
     &:focus,

+ 64 - 0
misago/emberapp/app/styles/misago/dropdowns.less

@@ -0,0 +1,64 @@
+//
+// Dropdowns
+// --------------------------------------------------
+
+
+// Dropdowns style
+.dropdown-menu {
+  border-radius: @dropdown-border-radius;
+  .box-shadow(@dropdown-shadow);
+}
+
+
+.dropdown-menu > li > a > .badge {
+  float: right;
+}
+
+.dropdown-space {
+  padding: 7px 20px;
+}
+
+.dropdown-footer {
+  background: @dropdown-footer-bg;
+  border-top: 1px solid @dropdown-footer-border;
+  border-radius: 0px 0px @dropdown-border-radius @dropdown-border-radius;
+  padding: 7px 20px;
+}
+
+
+// User dropdown
+.user-dropdown {
+  width: 300px;
+  padding: 0px;
+
+  .user-preview, .guest-preview {
+    border-bottom: 1px solid @dropdown-divider-bg;
+    margin-bottom: 8px;
+    padding: 12px 20px;
+
+    .editable-avatar {
+      margin-right: 4px;
+    }
+
+    .row {
+      margin-top: @line-height-computed * 1.3;
+
+      div:first-child {
+        padding-right: 4px;
+      }
+
+      div:last-child {
+        padding-left: 4px;
+      }
+    }
+  }
+
+  .guest-preview {
+    border-bottom: 0px;
+    margin-bottom: 4px;
+  }
+
+  .dropdown-footer {
+    margin-top: 8px;
+  }
+}

+ 1 - 3
misago/emberapp/app/styles/misago/footer.less

@@ -4,7 +4,7 @@
 
 
 .site-footer {
-  margin-top: @line-height-computed * 1.5;
+  margin-top: @line-height-computed;
   padding-bottom: @line-height-computed * 1.5;
 
   color: @footer-color;
@@ -40,8 +40,6 @@
 
   /* Big devices (tablets, 768px and up) */
   @media (min-width: @screen-sm-min) {
-    margin-top: @line-height-computed * 2;
-    padding-top: @line-height-computed * 1.5;
     overflow: auto;
 
     text-align: left;

+ 2 - 0
misago/emberapp/app/styles/misago/misago.less

@@ -1,5 +1,6 @@
 // Components
 @import "buttons.less";
+@import "dropdowns.less";
 @import "toast-message.less";
 @import "footer.less";
 @import "forms.less";
@@ -8,6 +9,7 @@
 @import "navbar.less";
 @import "page-header.less";
 @import "typo.less";
+@import "misc.less";
 
 // Pages
 @import "errorpages.less";

+ 41 - 0
misago/emberapp/app/styles/misago/misc.less

@@ -0,0 +1,41 @@
+//
+// Misc utils
+// --------------------------------------------------
+
+
+
+// Avatar with "edit" button
+.editable-avatar {
+  background: none;
+  border-radius: @border-radius-base;
+
+  margin: 0px;
+  padding: 0px;
+
+  position: relative;
+  overflow: hidden;
+
+  .help {
+    background: fadeOut(#000, 30%);
+    border-radius: 0px;
+    display: block;
+    margin: 0px;
+    padding: 4px 0px;
+    width: 100%;
+
+    .opacity(0.6);
+
+    position: absolute;
+    bottom: 0px;
+
+    color: #fff;
+    font-size: @font-size-small;
+    text-shadow: 1px 1px 0px #000;
+  }
+
+  &:hover, &:focus {
+    .help {
+      .opacity(1);
+    }
+  }
+}

+ 187 - 18
misago/emberapp/app/styles/misago/navbar.less

@@ -3,52 +3,221 @@
 // --------------------------------------------------
 
 
+// Affixed navbar
+.navbar-spacer {
+  margin-bottom: @line-height-computed;
+
+  .navbar-primary {
+    border-bottom-width: 1px;
+    margin: 0px;
+
+    &.affix {
+      .box-shadow(0px 0px 3px fadeOut(#333, 70%));
+
+      width: 100%;
+      top: 0px;
+    }
+  }
+}
+
+
 // Navbar brand
 .navbar-primary {
-  border-bottom-width: 1px;
-
   .navbar-brand {
     font-size: @font-size-large * 1.2;
+    font-weight: @weight-light;
 
     img {
-      border-radius: @border-radius-small;
       display: inline-block;
-      height: @navbar-height - @navbar-padding-vertical * 2 + 3px;
+      height: @navbar-brand-height;
+      margin: ((@line-height-computed - @navbar-brand-height) / 2) 0px;
 
       position: relative;
-      bottom: 2px;
+      bottom: 3px;
     }
   }
 }
 
 
-// Navbar nav
+// Navbar navs
 .navbar-primary {
   .navbar-nav {
+    float: left;
 
-    // Make icons bigger
     &>li {
+      float: left;
+
       &>a {
-        .fa, .glyphicon {
-          position: relative;
-          top: (@font-size-large - @font-size-base) / 2 + 1px;
+        // Scale links up
+        font-size: @navbar-link-size;
+
+        // We don't use .active states in navbar
+        &:active, &:focus {
+          color: @navbar-default-link-active-color;
+        }
 
-          font-size: @font-size-large;
+        // Align badges to glyhps
+        &>.badge {
+          vertical-align: inherit;
+          margin: (@line-height-computed / -2) 0px;
+        }
+
+        &>.glyphicon {
+          position: relative;
+          top: 4px;
         }
       }
     }
+  }
+}
+
 
-    // Uncollapse the nav
+// User Menu
+.navbar-primary {
+  .navbar-user-nav {
     float: right;
-    margin: 0;
 
-    > li {
-      float: left;
-      > a {
-        padding-top:    @navbar-padding-vertical;
-        padding-bottom: @navbar-padding-vertical;
+    .btn-success {
+      position: relative;
+      top: 1px;
+    }
+  }
+
+  .user-menu {
+    .dropdown-toggle {
+      .fa {
+        font-size: @font-size-base;
       }
+
+      img {
+        border-radius: @avatar-radius-small;
+        margin: (@line-height-computed / -2) 0px;
+
+        width: 28px;
+        height: 28px;
+      }
+    }
+  }
+}
+
+
+// Guest Menu
+.navbar-primary {
+  .navbar-guest-nav {
+    float: right;
+
+    .btn {
+      position: relative;
+      top: 1px;
     }
+  }
+}
+
+
+// Dropdowns
+.navbar-static-top {
+  & .navbar-nav > li > .dropdown-menu {
+    border-radius: @dropdown-border-radius;
+  }
+}
 
+
+// Compact nav
+@media (max-width: @screen-sm-max) {
+  .navbar-primary {
+    min-height: @navbar-compact-height;
+  }
+}
+
+.navbar-primary {
+  .navbar-compact-nav {
+    margin: 0px;
+    float: none;
+    width: 100%;
+
+    &>li {
+      &>a {
+        padding: @navbar-compact-padding-vertical 0px;
+        height: @navbar-compact-height;
+
+        text-align: center;
+
+        // Align glyphs to middle of height
+        .glyphicon {
+          position: static;
+
+          font-size: 20px;
+        }
+
+        // Align images
+        img {
+          width: 28px;
+          margin: ((@line-height-computed - 28) / 2) 0px;
+
+          position: relative;
+          bottom: 2px;
+        }
+
+        // Custom touched style
+        &:active {
+          background-color: @navbar-compact-link-active-bg;
+
+          color: @navbar-compact-link-active-color;
+        }
+      }
+    }
+
+    .dropdown {
+      &.open .dropdown-toggle {
+        background-color: @navbar-compact-link-active-bg;
+
+        color: @navbar-compact-link-active-color;
+      }
+
+      .dropdown-menu {
+        position: absolute;
+        float: right;
+        width: 300px;
+        margin-top: 2px;
+        background-color: @dropdown-bg;
+        border: 1px solid @dropdown-fallback-border; // IE8 fallback
+        border: 1px solid @dropdown-border;
+        border-radius: @dropdown-border-radius;
+        .box-shadow(@dropdown-shadow);
+      }
+    }
+
+    // Even widths
+    &.with-4-links {
+      &>li {
+        width: 25%;
+      }
+    }
+
+    &.with-5-links {
+      &>li {
+        width: 20%;
+      }
+    }
+
+    &.with-6-links {
+      &>li {
+        width: 16%;
+
+        &:first-child, &:last-child {
+          width: 18%;
+        }
+      }
+    }
+
+    &.with-7-links {
+      &>li {
+        width: 14%;
+
+        &:first-child, &:last-child {
+          width: 15%;
+        }
+      }
+    }
   }
 }

+ 60 - 5
misago/emberapp/app/styles/misago/variables.less

@@ -14,7 +14,7 @@
 @gray-light:             lighten(@gray-base, 46.7%); // #777
 @gray-lighter:           lighten(@gray-base, 93.5%); // #eee
 
-@brand-info:             #ff5722; // misago uses info state for accents
+@brand-info:             #e66a5d; // misago uses info state for accents
 
 @brand-primary:          #3498db;
 @brand-success:          #2ecc71;
@@ -52,6 +52,11 @@
 @state-clicked:         @brand-primary;
 
 
+//** Avatar radius
+@avatar-radius:             8px;
+@avatar-radius-small:       4px;
+
+
 //== Typography
 //
 //## headings
@@ -61,12 +66,29 @@
 @headings-color:          lighten(@text-color, 8%);;
 
 
+//== Badges
+//
+//##
+
+@badge-color:                 #fff;
+//** Linked badge text color on hover
+@badge-link-hover-color:      #fff;
+@badge-bg:                    @brand-info;
+
+//** Badge text color in active nav link
+@badge-active-color:          @link-color;
+//** Badge background color in active nav link
+@badge-active-bg:             #fff;
+
+@badge-font-weight:           @weight-light;
+
+
 //== Navbar
 //
 //##
 
 // Basics of a navbar
-@navbar-height:                    50px;
+@navbar-height:                    46px;
 @navbar-margin-bottom:             @line-height-computed;
 @navbar-border-radius:             @border-radius-base;
 @navbar-padding-horizontal:        floor((@grid-gutter-width / 2));
@@ -78,16 +100,26 @@
 @navbar-default-border:            @gray-lighter;
 
 // Navbar links
-@navbar-default-link-color:                darken(@gray-lighter, 20%);
-@navbar-default-link-hover-color:          @gray-light;
+@navbar-link-size:                         @font-size-base + 2px;
+
+@navbar-default-link-color:                @site-link-color;
+@navbar-default-link-hover-color:          @site-link-hover-color;
 @navbar-default-link-hover-bg:             transparent;
-@navbar-default-link-active-color:         @gray-darker;
+@navbar-default-link-active-color:         @site-link-active-color;
 @navbar-default-link-active-bg:            transparent;
 
+@navbar-compact-link-active-color:         @navbar-default-bg;
+@navbar-compact-link-active-bg:            @site-link-active-color;
+
 // Navbar brand label
 @navbar-default-brand-color:               @headings-color;
 @navbar-default-brand-hover-color:         @headings-color;
 
+@navbar-brand-height:                      @navbar-height - @navbar-padding-vertical * 2 + 3px;
+
+// Compact navbar, used on mobiles
+@navbar-compact-height:                    40px;
+@navbar-compact-padding-vertical:          ((@navbar-compact-height - @line-height-computed) / 2);
 
 //== Site Footer
 //
@@ -221,3 +253,26 @@
 
 @panel-form-footer-bg:              @panel-form-bg;
 @panel-form-footer-border:          darken(@panel-form-bg, 10%);
+
+
+//== Dropdowns
+//
+//** Dropdown radius and shadow
+@dropdown-border-radius:            @border-radius-base;
+@dropdown-shadow:                   0px 0px 0px 3px fadeOut(@gray, 50%);
+
+//** Dropdown link text color.
+@dropdown-link-color:            @site-link-color;
+//** Hover color for dropdown links.
+@dropdown-link-hover-color:      @site-link-hover-color;
+//** Hover background for dropdown links.
+@dropdown-link-hover-bg:         transparent;
+
+//** Active dropdown menu item text color.
+@dropdown-link-active-color:     @site-link-active-color;
+//** Active dropdown menu item background color.
+@dropdown-link-active-bg:        transparent;
+
+//** Dropdown footer bg and border
+@dropdown-footer-border:         darken(@dropdown-bg, 10%);
+@dropdown-footer-bg:             darken(@dropdown-bg, 3%);

+ 2 - 1
misago/emberapp/app/templates/application.hbs

@@ -1,4 +1,4 @@
-{{render "navbar"}}
+{{forum-navbar}}
 {{toast-message}}
 
 <div class="main-outlet">
@@ -6,6 +6,7 @@
 </div>
 
 {{forum-footer}}
+
 <div class="modal fade" id="appModal" tabindex="-1" role="dialog" aria-labelledby="appModalLabel" aria-hidden="true">
   {{outlet "modal"}}
 </div>

+ 1 - 1
misago/emberapp/app/templates/components/forms/login-form.hbs

@@ -29,7 +29,7 @@
     {{/if}}
   {{/if}}
 
-  {{#close-modal-button class="btn btn-block btn-default" goto="forgotten-password"}}
+  {{#close-modal-button class="btn btn-block btn-outlined btn-default" goto="forgotten-password"}}
     {{gettext "Forgot password?"}}
   {{/close-modal-button}}
 

+ 30 - 32
misago/emberapp/app/templates/components/forum-footer.hbs

@@ -1,39 +1,37 @@
-<footer class="site-footer">
-  <div class="container">
-    <div class="footer-content">
+<div class="container">
+  <div class="footer-content">
 
-      {{#if hasContent}}
-      <ul class="list-inline footer-nav">
-        {{#if settings.forum_footnote}}
-          <li class="site-footnote">
-            {{settings.forum_footnote}}
-          </li>
-        {{/if}}
-        {{#if showTermsLink}}
-          <li>
-          {{#if settings.terms_of_service_link }}
-            <a href="{{unbound settings.terms_of_service_link}}">{{gettext "Terms of service" }}</a>
-          {{else}}
-            {{#link-to 'terms-of-service'}}{{gettext "Terms of service" }}{{/link-to}}
-          {{/if}}
-          </li>
+    {{#if hasContent}}
+    <ul class="list-inline footer-nav">
+      {{#if settings.forum_footnote}}
+        <li class="site-footnote">
+          {{settings.forum_footnote}}
+        </li>
+      {{/if}}
+      {{#if showTermsLink}}
+        <li>
+        {{#if settings.terms_of_service_link }}
+          <a href="{{unbound settings.terms_of_service_link}}">{{gettext "Terms of service" }}</a>
+        {{else}}
+          {{#link-to 'terms-of-service'}}{{gettext "Terms of service" }}{{/link-to}}
         {{/if}}
-        {{#if showPrivacyLink}}
-          <li>
-          {{#if settings.privacy_policy_link }}
-            <a href="{{unbound settings.privacy_policy_link}}">{{gettext "Privacy policy" }}</a>
-          {{else}}
-            {{#link-to 'privacy-policy'}}{{gettext "Privacy policy" }}{{/link-to}}
-          {{/if}}
-          </li>
+        </li>
+      {{/if}}
+      {{#if showPrivacyLink}}
+        <li>
+        {{#if settings.privacy_policy_link }}
+          <a href="{{unbound settings.privacy_policy_link}}">{{gettext "Privacy policy" }}</a>
+        {{else}}
+          {{#link-to 'privacy-policy'}}{{gettext "Privacy policy" }}{{/link-to}}
         {{/if}}
-      </ul>
+        </li>
       {{/if}}
+    </ul>
+    {{/if}}
 
-      <a href="http://misago-project.org" class="misago-branding">
-        powered by <strong>misago</strong>
-      </a>
+    <a href="http://misago-project.org" class="misago-branding">
+      powered by <strong>misago</strong>
+    </a>
 
-    </div>
   </div>
-</footer>
+</div>

+ 153 - 0
misago/emberapp/app/templates/components/forum-navbar.hbs

@@ -0,0 +1,153 @@
+<nav class="navbar navbar-primary navbar-default navbar-static-top" role="navigation">
+  <div class="container">
+
+    {{#if settings.forum_branding_display}}
+      {{#link-to 'index' class="navbar-brand hidden-xs hidden-sm"}}
+        <img src="{{unbound staticUrl}}misago/img/site-logo.png" alt="">
+        {{#if settings.forum_branding_text}}
+          <span class="hidden-xs hidden-sm">{{settings.forum_branding_text}}</span>
+        {{/if}}
+      {{/link-to}}
+    {{/if}}
+
+    <ul class="nav navbar-nav hidden-xs hidden-sm">
+      <li>
+        <a href="#">
+          {{gettext "Threads"}}
+        </a>
+      </li>
+      <li>
+        <a href="#">
+          {{gettext "Forums"}}
+        </a>
+      </li>
+      <li>
+        <a href="#">
+          {{gettext "Feeds"}}
+        </a>
+      </li>
+      <li>
+        <a href="#">
+          {{gettext "Users"}}
+        </a>
+      </li>
+      <li>
+        <a href="#">
+          {{gettext "Search"}}
+        </a>
+      </li>
+    </ul>
+
+    {{#if auth.isAuthenticated}}
+    <ul class="nav navbar-nav navbar-user-nav hidden-xs hidden-sm">
+      <li class="">
+        <a href="#">
+          <span class="fa fa-exclamation-triangle fa-lg"></span>
+          <span class="badge">132</span>
+        </a>
+      </li>
+      <li class="user-notices dropdown">
+        <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
+          <span class="fa fa-bell-o fa-lg"></span>
+          <span class="badge">132</span>
+        </a>
+        <ul class="dropdown-menu" role="menu">
+          <li><a href="#">Action</a></li>
+          <li><a href="#">Another action</a></li>
+          <li><a href="#">Something else here</a></li>
+          <li class="divider"></li>
+          <li><a href="#">Separated link</a></li>
+        </ul>
+      </li>
+      {{user-nav}}
+      <li>
+        <button type="button" class="btn btn-outlined btn-success navbar-btn">
+          <span class="glyphicon glyphicon-comment"></span>
+          {{gettext "Start thread"}}
+        </button>
+      </li>
+    </ul>
+    {{else}}
+    <div class="navbar-guest-nav hidden-xs hidden-sm">
+      <button type="button" class="btn btn-outlined btn-default navbar-btn" {{action "showModal" "login"}}>
+        {{gettext "Sign in"}}
+      </button>
+
+      {{#register-button class="btn btn-outlined btn-success navbar-btn"}}
+        {{gettext "Register account"}}
+      {{/register-button}}
+    </div>
+    {{/if}}
+  </div><!-- /full navbar -->
+
+  <ul class="nav navbar-nav navbar-compact-nav hidden-md hidden-lg {{if settings.forum_branding_display "with-7-links" "with-6-links"}}">
+    {{#if settings.forum_branding_display}}
+    <li class="compact-brand">
+      <a href="#">
+        <img src="{{unbound staticUrl}}misago/img/site-icon.png" alt="">
+      </a>
+    </li>
+    {{/if}}
+    <li>
+      <a href="#">
+        <span class="glyphicon glyphicon-comment"></span>
+      </a>
+    </li>
+    <li>
+      <a href="#">
+        <span class="glyphicon glyphicon-th-list"></span>
+      </a>
+    </li>
+    <li>
+      <a href="#">
+        <span class="glyphicon glyphicon-heart-empty"></span>
+      </a>
+    </li>
+    <li>
+      <a href="#">
+        <span class="glyphicon glyphicon-user"></span>
+      </a>
+    </li>
+    <li>
+      <a href="#">
+        <span class="glyphicon glyphicon-search"></span>
+      </a>
+    </li>
+    {{#if auth.isAuthenticated}}
+    {{user-nav}}
+    {{else}}
+    <li class="user-menu dropdown">
+      <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
+        {{user-avatar size=28}}
+      </a>
+      <ul class="dropdown-menu user-dropdown dropdown-menu-right" role="menu">
+        <li class="guest-preview">
+
+          <div class="media">
+            <div class="media-body">
+
+              <h4 class="media-heading">{{gettext "You are browsing as guest."}}</h4>
+
+              <div class="row">
+                <div class="col-xs-6">
+                  <button type="button" class="btn btn-outlined btn-default btn-block btn-sm" {{action "showModal" "login"}}>
+                    {{gettext "Sign in"}}
+                  </button>
+                </div>
+                <div class="col-xs-6">
+                  {{#register-button class="btn btn-outlined btn-success btn-block btn-sm"}}
+                    {{gettext "Register account"}}
+                  {{/register-button}}
+                </div>
+              </div>
+
+            </div>
+          </div>
+
+        </li>
+      </ul>
+    </li>
+    {{/if}}
+  </ul>
+  <!-- /.compact navbar -->
+</nav>

+ 83 - 4
misago/emberapp/app/templates/components/user-nav.hbs

@@ -1,4 +1,83 @@
-<p class="navbar-text">
-  {{user-avatar id=auth.user.id size=200}}
-  {{auth.user.username}}
-</p>
+<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
+  {{user-avatar user=auth.user.id size=28}}
+  <span class="fa fa-bars hidden-xs hidden-sm"></span>
+</a>
+<ul class="dropdown-menu user-dropdown dropdown-menu-right" role="menu">
+  <li class="user-preview">
+
+    <div class="media">
+      <div class="media-left">
+
+        <button type="button" class="btn editable-avatar">
+          {{user-avatar user=auth.user.id size=100}}
+          <div class="help">
+            {{gettext "Change avatar"}}
+          </div>
+        </button>
+
+      </div>
+      <div class="media-body">
+
+        <h4 class="media-heading">{{auth.user.username}}</h4>
+
+        <p class="text-muted">
+          {{auth.user.full_title}}
+        </p>
+
+        <div class="row">
+          <div class="col-xs-6">
+            <button type="button" class="btn btn-outlined btn-default btn-block btn-sm">
+              {{gettext "Profile"}}
+            </button>
+          </div>
+          <div class="col-xs-6">
+            <button type="button" class="btn btn-outlined btn-default btn-block btn-sm">
+              {{gettext "Options"}}
+            </button>
+          </div>
+        </div>
+
+      </div>
+    </div>
+
+  </li>
+  <li class="dropdown-space hidden-md hidden-lg">
+    <button type="button" class="btn btn-outlined btn-success btn-block">
+      <span class="glyphicon glyphicon-comment"></span>
+      {{gettext "Start thread"}}
+    </button>
+  </li>
+  <li class="divider hidden-md hidden-lg"></li>
+  <li>
+    <a href="#">
+      <span class="fa fa-exclamation-triangle fa-fw"></span>
+      {{gettext "Reports"}}
+      <span class="badge">132</span>
+    </a>
+  </li>
+  <li>
+    <a href="#">
+      <span class="fa fa-bell-o fa-fw"></span>
+      {{gettext "Notifications"}}
+      <span class="badge">132</span>
+    </a>
+  </li>
+  <li>
+    <a href="#">
+      <span class="fa fa-inbox fa-fw"></span>
+      {{gettext "Private threads"}}
+      <span class="badge">132</span>
+    </a>
+  </li>
+  <li>
+    <a href="#">
+      <span class="fa fa-bookmark fa-fw"></span>
+      {{gettext "Subscriptions"}}
+    </a>
+  </li>
+  <li class="dropdown-footer">
+    <button type="button" class="btn btn-outlined btn-default btn-block" {{action "logout"}}>
+      {{gettext "Log out"}}
+    </button>
+  </li>
+</ul>

+ 30 - 10
misago/emberapp/app/templates/index.hbs

@@ -1,20 +1,40 @@
 <div class="container">
   <h1>Welcome to Ember.js!</h1>
-  <p class="lead">IndexController renders index.hbs template!</p>
+
+  <p class="lead">
+    Lorem ipsum dolor met sit amet elit.
+  </p>
+
   <p class="lead">
-    Special pages: {{#link-to 'loading'}}Loading{{/link-to}}, {{#link-to 'error-0'}}Connection lost{{/link-to}}, {{#link-to 'error-404'}}Error 404{{/link-to}}.
+    Si vis pacem para bellum.
   </p>
 
-  <hr>
+  <p class="lead">
+    Lorem ipsum dolor met sit amet elit.
+  </p>
 
-  <h2>{{gettext "Test %(msg)s Message" msg=(gettext "Flash")}}</h2>
+  <p class="lead">
+    Lorem ipsum dolor met sit amet elit.
+  </p>
+
+  <p class="lead">
+    Lorem ipsum dolor met sit amet elit.
+  </p>
 
-  <p>
-    {{input class="testinput" type="text" value=newFlash}}
-    <button class="btn btn-primary" {{action "testInfo"}}>Info</button>
-    <button class="btn btn-success" {{action "testSuccess"}}>Success</button>
-    <button class="btn btn-warning" {{action "testWarning"}}>Warning</button>
-    <button class="btn btn-danger" {{action "testError"}}>Error</button>
+  <p class="lead">
+    Lorem ipsum dolor met sit amet elit.
+  </p>
+
+  <p class="lead">
+    Lorem ipsum dolor met sit amet elit.
+  </p>
+
+  <p class="lead">
+    Lorem ipsum dolor met sit amet elit.
+  </p>
+
+  <p class="lead">
+    Lorem ipsum dolor met sit amet elit.
   </p>
 
 </div>

+ 145 - 16
misago/emberapp/app/templates/navbar.hbs

@@ -1,24 +1,153 @@
 <nav class="navbar navbar-primary navbar-default navbar-static-top" role="navigation">
-  <div class="container">
+<div class="container">
 
-    {{#link-to 'index' class="navbar-brand"}}
-      <img src="{{unbound staticUrl}}misago/img/misago_logo.png" alt="">
-      <span>{{settings.forum_name}}</span>
+  {{#if settings.forum_branding_display}}
+    {{#link-to 'index' class="navbar-brand hidden-xs hidden-sm"}}
+      <img src="{{unbound staticUrl}}misago/img/site-logo.png" alt="">
+      {{#if settings.forum_branding_text}}
+        <span class="hidden-xs hidden-sm">{{settings.forum_branding_text}}</span>
+      {{/if}}
     {{/link-to}}
+  {{/if}}
 
-    {{#if auth.isAuthenticated}}
-      {{user-nav}}
-    {{else}}
-    <div class="guest-nav navbar-right">
-      <button type="button" class="btn btn-default btn-login navbar-btn btn-sm" {{action "showModal" "login"}}>
-        {{gettext "Sign in"}}
+  <ul class="nav navbar-nav hidden-xs hidden-sm">
+    <li>
+      <a href="#">
+        {{gettext "Threads"}}
+      </a>
+    </li>
+    <li>
+      <a href="#">
+        {{gettext "Forums"}}
+      </a>
+    </li>
+    <li>
+      <a href="#">
+        {{gettext "Feeds"}}
+      </a>
+    </li>
+    <li>
+      <a href="#">
+        {{gettext "Users"}}
+      </a>
+    </li>
+    <li>
+      <a href="#">
+        {{gettext "Search"}}
+      </a>
+    </li>
+  </ul>
+
+  {{#if auth.isAuthenticated}}
+  <ul class="nav navbar-nav navbar-user-nav hidden-xs hidden-sm">
+    <li class="">
+      <a href="#">
+        <span class="fa fa-exclamation-triangle fa-lg"></span>
+        <span class="badge">132</span>
+      </a>
+    </li>
+    <li class="user-notices dropdown">
+      <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
+        <span class="fa fa-bell-o fa-lg"></span>
+        <span class="badge">132</span>
+      </a>
+      <ul class="dropdown-menu" role="menu">
+        <li><a href="#">Action</a></li>
+        <li><a href="#">Another action</a></li>
+        <li><a href="#">Something else here</a></li>
+        <li class="divider"></li>
+        <li><a href="#">Separated link</a></li>
+      </ul>
+    </li>
+    {{user-nav}}
+    <li>
+      <button type="button" class="btn btn-outlined btn-success navbar-btn">
+        <span class="glyphicon glyphicon-comment"></span>
+        {{gettext "Start thread"}}
       </button>
+    </li>
+  </ul>
+  {{else}}
+  <div class="navbar-guest-nav hidden-xs hidden-sm">
+    <button type="button" class="btn btn-outlined btn-default navbar-btn" {{action "showModal" "login"}}>
+      {{gettext "Sign in"}}
+    </button>
+
+    {{#register-button class="btn btn-outlined btn-success navbar-btn"}}
+      {{gettext "Register account"}}
+    {{/register-button}}
+  </div>
+  {{/if}}
+</div><!-- /full navbar -->
+
+<ul class="nav navbar-nav navbar-compact-nav hidden-md hidden-lg {{if settings.forum_branding_display "with-7-links" "with-6-links"}}">
+  {{#if settings.forum_branding_display}}
+  <li class="compact-brand">
+    <a href="#">
+      <img src="{{unbound staticUrl}}misago/img/site-icon.png" alt="">
+    </a>
+  </li>
+  {{/if}}
+  <li>
+    <a href="#">
+      <span class="glyphicon glyphicon-comment"></span>
+    </a>
+  </li>
+  <li>
+    <a href="#">
+      <span class="glyphicon glyphicon-th-list"></span>
+    </a>
+  </li>
+  <li>
+    <a href="#">
+      <span class="glyphicon glyphicon-heart-empty"></span>
+    </a>
+  </li>
+  <li>
+    <a href="#">
+      <span class="glyphicon glyphicon-user"></span>
+    </a>
+  </li>
+  <li>
+    <a href="#">
+      <span class="glyphicon glyphicon-search"></span>
+    </a>
+  </li>
+  {{#if auth.isAuthenticated}}
+  {{user-nav}}
+  {{else}}
+  <li class="user-menu dropdown">
+    <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
+      {{user-avatar size=28}}
+    </a>
+    <ul class="dropdown-menu user-dropdown dropdown-menu-right" role="menu">
+      <li class="guest-preview">
+
+        <div class="media">
+          <div class="media-body">
+
+            <h4 class="media-heading">{{gettext "You are browsing as guest."}}</h4>
+
+            <div class="row">
+              <div class="col-xs-6">
+                <button type="button" class="btn btn-outlined btn-default btn-block btn-sm" {{action "showModal" "login"}}>
+                  {{gettext "Sign in"}}
+                </button>
+              </div>
+              <div class="col-xs-6">
+                {{#register-button class="btn btn-outlined btn-success btn-block btn-sm"}}
+                  {{gettext "Register account"}}
+                {{/register-button}}
+              </div>
+            </div>
 
-      {{#register-button class="btn btn-info btn-join navbar-btn btn-sm"}}
-        {{gettext "Join now"}}
-      {{/register-button}}
-    </div>
-    {{/if}}
+          </div>
+        </div>
 
-  </div><!-- /.container -->
+      </li>
+    </ul>
+  </li>
+  {{/if}}
+</ul>
+<!-- /.compact navbar -->
 </nav>

BIN
misago/emberapp/public/misago/img/misago_logo.png


BIN
misago/emberapp/public/misago/img/site-icon.png


BIN
misago/emberapp/public/misago/img/site-logo.png


+ 11 - 11
misago/emberapp/tests/acceptance/error-toast-test.js

@@ -5,7 +5,7 @@ import getToastMessage from '../helpers/toast-message';
 
 var application;
 
-module('Acceptance: Application Error Handler', {
+module('Acceptance: Toasting Error Handler', {
   beforeEach: function() {
     application = startApp();
   },
@@ -21,13 +21,13 @@ test('some unhandled error occured', function(assert) {
   assert.expect(1);
 
   Ember.$.mockjax({
-    url: '/api/auth/login/',
+    url: '/api/auth/',
     status: 500
   });
 
   visit('/');
 
-  click('.guest-nav .btn-login');
+  click('.navbar-guest-nav button.btn-default');
   fillIn('#appModal .form-group:first-child input', 'SomeFake');
   fillIn('#appModal .form-group:last-child input', 'pass1234');
   click('#appModal .btn-primary');
@@ -41,13 +41,13 @@ test('app went away', function(assert) {
   assert.expect(1);
 
   Ember.$.mockjax({
-    url: '/api/auth/login/',
+    url: '/api/auth/',
     status: 0
   });
 
   visit('/');
 
-  click('.guest-nav .btn-login');
+  click('.navbar-guest-nav button.btn-default');
   fillIn('#appModal .form-group:first-child input', 'SomeFake');
   fillIn('#appModal .form-group:last-child input', 'pass1234');
   click('#appModal .btn-primary');
@@ -61,7 +61,7 @@ test('not found', function(assert) {
   assert.expect(1);
 
   Ember.$.mockjax({
-    url: '/api/auth/login/',
+    url: '/api/auth/',
     status: 404,
     responseText: {
       'detail': 'Not found'
@@ -70,7 +70,7 @@ test('not found', function(assert) {
 
   visit('/');
 
-  click('.guest-nav .btn-login');
+  click('.navbar-guest-nav button.btn-default');
   fillIn('#appModal .form-group:first-child input', 'SomeFake');
   fillIn('#appModal .form-group:last-child input', 'pass1234');
   click('#appModal .btn-primary');
@@ -84,7 +84,7 @@ test('permission denied', function(assert) {
   assert.expect(1);
 
   Ember.$.mockjax({
-    url: '/api/auth/login/',
+    url: '/api/auth/',
     status: 403,
     responseText: {
       'detail': 'Permission denied'
@@ -93,7 +93,7 @@ test('permission denied', function(assert) {
 
   visit('/');
 
-  click('.guest-nav .btn-login');
+  click('.navbar-guest-nav button.btn-default');
   fillIn('#appModal .form-group:first-child input', 'SomeFake');
   fillIn('#appModal .form-group:last-child input', 'pass1234');
   click('#appModal .btn-primary');
@@ -107,7 +107,7 @@ test('permission denied with reason', function(assert) {
   assert.expect(1);
 
   Ember.$.mockjax({
-    url: '/api/auth/login/',
+    url: '/api/auth/',
     status: 403,
     responseText: {
       'detail': 'Lorem ipsum dolor met.'
@@ -116,7 +116,7 @@ test('permission denied with reason', function(assert) {
 
   visit('/');
 
-  click('.guest-nav .btn-login');
+  click('.navbar-guest-nav button.btn-default');
   fillIn('#appModal .form-group:first-child input', 'SomeFake');
   fillIn('#appModal .form-group:last-child input', 'pass1234');
   click('#appModal .btn-primary');

+ 13 - 13
misago/emberapp/tests/acceptance/login-test.js

@@ -27,7 +27,7 @@ test('login with empty credentials', function(assert) {
   assert.expect(1);
 
   visit('/');
-  click('.guest-nav button.btn-login');
+  click('.navbar-guest-nav button.btn-default');
   click('#appModal .btn-primary');
 
   andThen(function() {
@@ -39,13 +39,13 @@ test('backend errored', function(assert) {
   assert.expect(1);
 
   Ember.$.mockjax({
-    url: "/api/auth/login/",
+    url: '/api/auth/',
     status: 500
   });
 
   visit('/');
 
-  click('.guest-nav .btn-login');
+  click('.navbar-guest-nav .btn-default');
   fillIn('#appModal .form-group:first-child input', 'SomeFake');
   fillIn('#appModal .form-group:last-child input', 'pass1234');
   click('#appModal .btn-primary');
@@ -60,7 +60,7 @@ test('login with invalid credentials', function(assert) {
 
   var message = 'Login or password is incorrect.';
   Ember.$.mockjax({
-    url: "/api/auth/login/",
+    url: '/api/auth/',
     status: 400,
     responseText: {
       'detail': message,
@@ -70,7 +70,7 @@ test('login with invalid credentials', function(assert) {
 
   visit('/');
 
-  click('.guest-nav .btn-login');
+  click('.navbar-guest-nav .btn-default');
   fillIn('#appModal .form-group:first-child input', 'SomeFake');
   fillIn('#appModal .form-group:last-child input', 'pass1234');
   click('#appModal .btn-primary');
@@ -85,7 +85,7 @@ test('login to user-activated account', function(assert) {
 
   var message = 'You have to activate your account before you will be able to sign in.';
   Ember.$.mockjax({
-    url: "/api/auth/login/",
+    url: '/api/auth/',
     status: 400,
     responseText: {
       'detail': message,
@@ -95,7 +95,7 @@ test('login to user-activated account', function(assert) {
 
   visit('/');
 
-  click('.guest-nav .btn-login');
+  click('.navbar-guest-nav .btn-default');
   fillIn('#appModal .form-group:first-child input', 'SomeFake');
   fillIn('#appModal .form-group:last-child input', 'pass1234');
   click('#appModal .btn-primary');
@@ -110,7 +110,7 @@ test('login to admin-activated account', function(assert) {
 
   var message = 'Your account has to be activated by Administrator before you will be able to sign in.';
   Ember.$.mockjax({
-    url: "/api/auth/login/",
+    url: '/api/auth/',
     status: 400,
     responseText: {
       'detail': message,
@@ -120,7 +120,7 @@ test('login to admin-activated account', function(assert) {
 
   visit('/');
 
-  click('.guest-nav .btn-login');
+  click('.navbar-guest-nav .btn-default');
   fillIn('#appModal .form-group:first-child input', 'SomeFake');
   fillIn('#appModal .form-group:last-child input', 'pass1234');
   click('#appModal .btn-primary');
@@ -134,7 +134,7 @@ test('login to banned account', function(assert) {
   assert.expect(3);
 
   Ember.$.mockjax({
-    url: "/api/auth/login/",
+    url: '/api/auth/',
     status: 400,
     responseText: {
       'detail': {
@@ -150,7 +150,7 @@ test('login to banned account', function(assert) {
 
   visit('/');
 
-  click('.guest-nav .btn-login');
+  click('.navbar-guest-nav .btn-default');
   fillIn('#appModal .form-group:first-child input', 'SomeFake');
   fillIn('#appModal .form-group:last-child input', 'pass1234');
   click('#appModal .btn-primary');
@@ -170,7 +170,7 @@ test('login successfully', function(assert) {
   assert.expect(2);
 
   Ember.$.mockjax({
-    url: "/api/auth/login/",
+    url: '/api/auth/',
     status: 200,
     responseText: {
       'username': 'SomeFake'
@@ -179,7 +179,7 @@ test('login successfully', function(assert) {
 
   visit('/');
 
-  click('.guest-nav .btn-login');
+  click('.navbar-guest-nav .btn-default');
   fillIn('#appModal .form-group:first-child input', 'SomeFake');
   fillIn('#appModal .form-group:last-child input', 'pass1234');
   click('#appModal .btn-primary');

+ 8 - 8
misago/emberapp/tests/acceptance/registration-test.js

@@ -25,7 +25,7 @@ test('registration is closed', function(assert) {
   assert.expect(1);
 
   visit('/');
-  click('.guest-nav button.btn-join');
+  click('.navbar-guest-nav button.btn-success');
 
   andThen(function() {
     assert.equal(Ember.$.trim(find('.modal-register-closed .lead').text()), 'New registrations are currently not being accepted.');
@@ -36,7 +36,7 @@ test('register with empty credentials', function(assert) {
   assert.expect(1);
 
   visit('/');
-  click('.guest-nav button.btn-join');
+  click('.navbar-guest-nav button.btn-success');
   click('#appModal .btn-primary');
 
   andThen(function() {
@@ -48,7 +48,7 @@ test('register with invalid credentials', function(assert) {
   assert.expect(1);
 
   visit('/');
-  click('.guest-nav button.btn-join');
+  click('.navbar-guest-nav button.btn-success');
   fillIn('#appModal #id_username', 'a');
   fillIn('#appModal #id_password', 'b');
   fillIn('#appModal #id_email', 'c');
@@ -68,7 +68,7 @@ test('register with rejected credentials', function(assert) {
   });
 
   visit('/');
-  click('.guest-nav button.btn-join');
+  click('.navbar-guest-nav button.btn-success');
   fillIn('#appModal #id_username', 'Lorem');
   fillIn('#appModal #id_password', 'ipsum123');
   fillIn('#appModal #id_email', 'lorem@ipsum.com');
@@ -98,7 +98,7 @@ test('register banned', function(assert) {
   });
 
   visit('/');
-  click('.guest-nav button.btn-join');
+  click('.navbar-guest-nav button.btn-success');
   fillIn('#appModal #id_username', 'Lorem');
   fillIn('#appModal #id_password', 'ipsum123');
   fillIn('#appModal #id_email', 'lorem@ipsum.com');
@@ -129,7 +129,7 @@ test('register active user', function(assert) {
   });
 
   visit('/');
-  click('.guest-nav button.btn-join');
+  click('.navbar-guest-nav button.btn-success');
   fillIn('#appModal #id_username', 'Lorem');
   fillIn('#appModal #id_password', 'ipsum123');
   fillIn('#appModal #id_email', 'lorem@ipsum.com');
@@ -155,7 +155,7 @@ test('register admin-activated user', function(assert) {
   });
 
   visit('/');
-  click('.guest-nav button.btn-join');
+  click('.navbar-guest-nav button.btn-success');
   fillIn('#appModal #id_username', 'Lorem');
   fillIn('#appModal #id_password', 'ipsum123');
   fillIn('#appModal #id_email', 'lorem@ipsum.com');
@@ -181,7 +181,7 @@ test('register self-activated user', function(assert) {
   });
 
   visit('/');
-  click('.guest-nav button.btn-join');
+  click('.navbar-guest-nav button.btn-success');
   fillIn('#appModal #id_username', 'Lorem');
   fillIn('#appModal #id_password', 'ipsum123');
   fillIn('#appModal #id_email', 'lorem@ipsum.com');

+ 1 - 1
misago/emberapp/vendor/testutils/misago-preload-data.js

@@ -19,7 +19,7 @@ window.MisagoData = {
     "privacy_policy_title": "Polityka prywatno\u015bci",
     "privacy_policy": true,
 
-    "loginApiUrl": "auth/login",
+    "loginApiUrl": "auth",
 
     "loginUrl": "/login/",
     "loginRedirectUrl": "/",

+ 1 - 0
misago/users/serializers/__init__.py

@@ -1,2 +1,3 @@
 from misago.users.serializers.ban import *
+from misago.users.serializers.rank import *
 from misago.users.serializers.user import *

+ 19 - 0
misago/users/serializers/rank.py

@@ -0,0 +1,19 @@
+from rest_framework import serializers
+
+from misago.users.models import Rank
+
+
+__ALL__ = ['RankSerializer']
+
+
+class RankSerializer(serializers.ModelSerializer):
+    class Meta:
+        model = Rank
+        fields = (
+            'id',
+            'name',
+            'slug',
+            'description',
+            'title',
+            'css_class',
+            'is_tab')

+ 5 - 0
misago/users/serializers/user.py

@@ -4,12 +4,14 @@ from rest_framework import serializers
 
 from misago.acl import serialize_acl
 
+from misago.users.serializers import RankSerializer
 
 __ALL__ = ['AuthenticatedUserSerializer', 'AnonymousUserSerializer']
 
 
 class AuthenticatedUserSerializer(serializers.ModelSerializer):
     acl = serializers.SerializerMethodField()
+    rank = RankSerializer(many=False, read_only=True)
 
     class Meta:
         model = get_user_model()
@@ -21,6 +23,9 @@ class AuthenticatedUserSerializer(serializers.ModelSerializer):
             'joined_on',
             'is_hiding_presence',
             'title',
+            'full_title',
+            'short_title',
+            'rank',
             'new_notifications',
             'limits_private_thread_invites_to',
             'unread_private_threads',