Browse Source

wip user profile layout

Rafał Pitoń 10 years ago
parent
commit
b1971a035d

+ 1 - 1
misago/emberapp/app/adapters/user-profile.js

@@ -1,7 +1,7 @@
 import MisagoAdapter from 'misago/adapters/application';
 import MisagoAdapter from 'misago/adapters/application';
 
 
 export default MisagoAdapter.extend({
 export default MisagoAdapter.extend({
-  pathForType: function(type) {
+  pathForType: function() {
     return 'users';
     return 'users';
   }
   }
 });
 });

+ 3 - 0
misago/emberapp/app/components/user-state-icon.js

@@ -0,0 +1,3 @@
+import UserStateLabel from 'misago/components/user-state-label';
+
+export default UserStateLabel.extend();

+ 70 - 0
misago/emberapp/app/components/user-state-label.js

@@ -0,0 +1,70 @@
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+  classNames: 'user-state',
+  classNameBindings: [
+    'user.state.is_banned:user-banned',
+    'user.state.is_hidden:user-hidden',
+    'user.state.is_online_hidden:user-online',
+    'user.state.is_offline_hidden:user-offline',
+    'user.state.is_online:user-online',
+    'user.state.is_offline:user-offline'
+  ],
+
+  attributeBindings: ['title'],
+
+  title: function() {
+    if (this.get('user.state.is_banned')) {
+      if (this.get('user.state.banned_until')) {
+        return interpolate(gettext('%(username)s\'s is banned until %(ban_expires)s.'), {
+            'username': this.get('user.username'),
+            'ban_expires': moment(this.get('user.state.banned_until')).format('LL, LT')
+          }, true);
+      } else {
+        return interpolate(gettext('%(username)s\'s is banned.'), {
+            'username': this.get('user.username')
+          }, true);
+      }
+
+    } else if (this.get('user.state.is_hidden')) {
+      return interpolate(gettext('%(username)s\'s activity is hidden.'), {
+          'username': this.get('user.username')
+        }, true);
+
+    } else if (this.get('user.state.is_online_hidden')) {
+      return interpolate(gettext('%(username)s is online and hidden.'), {
+          'username': this.get('user.username')
+        }, true);
+
+    } else if (this.get('user.state.is_offline_hidden')) {
+      return interpolate(gettext('%(username)s was last seen hidden %(last_click)s.'), {
+          'username': this.get('user.username'),
+          'last_click': this.get('lastClick').fromNow()
+        }, true);
+
+    } else if (this.get('user.state.is_online')) {
+      return interpolate(gettext('%(username)s is online.'), {
+          'username': this.get('user.username')
+        }, true);
+
+    } else if (this.get('user.state.is_offline')) {
+      return interpolate(gettext('%(username)s was last seen %(last_click)s.'), {
+          'username': this.get('user.username'),
+          'last_click': this.get('lastClick').fromNow()
+        }, true);
+    }
+  }.property(
+    'user.state.is_banned',
+    'user.state.is_hidden',
+    'user.state.is_online_hidden',
+    'user.state.is_offline_hidden',
+    'user.state.is_online',
+    'user.state.is_offline',
+    'user.state.banned_until',
+    'lastClick'
+  ),
+
+  lastClick: function() {
+    return moment(this.get('user.state.last_click'));
+  }.property('user.state.last_click', 'clock.tick')
+});

+ 7 - 3
misago/emberapp/app/helpers/from-now.js

@@ -1,10 +1,14 @@
 import Ember from 'ember';
 import Ember from 'ember';
 
 
 export function fromNow(input, options) {
 export function fromNow(input, options) {
-  if (typeof options !== 'undefined' && typeof options.hash.nosuffix !== 'undefined') {
-    return input.fromNow(options.hash.nosuffix);
+  if (input) {
+    if (typeof options !== 'undefined' && typeof options.hash.nosuffix !== 'undefined') {
+      return input.fromNow(options.hash.nosuffix);
+    } else {
+      return input.fromNow();
+    }
   } else {
   } else {
-    return input.fromNow();
+    return gettext('never');
   }
   }
 }
 }
 
 

+ 13 - 2
misago/emberapp/app/mixins/shared-user-attrs.js

@@ -1,3 +1,4 @@
+import Ember from 'ember';
 import DS from 'ember-data';
 import DS from 'ember-data';
 import WithUrlName from 'misago/mixins/with-url-name';
 import WithUrlName from 'misago/mixins/with-url-name';
 
 
@@ -7,6 +8,16 @@ export default Ember.Mixin.create(WithUrlName, {
   avatar_hash: DS.attr('string'),
   avatar_hash: DS.attr('string'),
   title: DS.attr('string'),
   title: DS.attr('string'),
   rank: DS.attr('ember-object'),
   rank: DS.attr('ember-object'),
-  state: DS.attr('string'),
-  signature: DS.attr('ember-object')
+  state: DS.attr('ember-object'),
+  signature: DS.attr('string'),
+
+  finalTitle: function() {
+    if (this.get('title')) {
+      return this.get('title');
+    } else if (this.get('rank.title')) {
+      return this.get('rank.title');
+    } else {
+      return '';
+    }
+  }.property('title', 'rank.title')
 });
 });

+ 1 - 0
misago/emberapp/app/models/user-profile.js

@@ -2,5 +2,6 @@ import DS from 'ember-data';
 import SharedUserAttrs from 'misago/mixins/shared-user-attrs';
 import SharedUserAttrs from 'misago/mixins/shared-user-attrs';
 
 
 export default DS.Model.extend(SharedUserAttrs, {
 export default DS.Model.extend(SharedUserAttrs, {
+  email: DS.attr('string'),
   acl: DS.attr('ember-object')
   acl: DS.attr('ember-object')
 });
 });

+ 1 - 0
misago/emberapp/app/models/user.js

@@ -1,3 +1,4 @@
+import DS from 'ember-data';
 import SharedUserAttrs from 'misago/mixins/shared-user-attrs';
 import SharedUserAttrs from 'misago/mixins/shared-user-attrs';
 
 
 export default DS.Model.extend(SharedUserAttrs);
 export default DS.Model.extend(SharedUserAttrs);

+ 16 - 8
misago/emberapp/app/services/auth.js

@@ -20,14 +20,6 @@ export default Ember.Service.extend({
     });
     });
   }.on('init'),
   }.on('init'),
 
 
-  setUrlNameOnUser: function() {
-    this.get('user').reopen({
-      url_name: function() {
-        return this.get('slug') + '-' + this.get('id');
-      }.property('id', 'slug')
-    });
-  }.on('init'),
-
   _handleAuthChange: function(isAuthenticated) {
   _handleAuthChange: function(isAuthenticated) {
     if (!this.get('needsSync')) {
     if (!this.get('needsSync')) {
       // display annoying "you were desynced" message
       // display annoying "you were desynced" message
@@ -66,6 +58,22 @@ export default Ember.Service.extend({
              'user.subscribe_to_started_threads',
              'user.subscribe_to_started_threads',
              'user.subscribe_to_replied_threads'),
              'user.subscribe_to_replied_threads'),
 
 
+  // User url name
+
+  setUrlNameOnUser: function() {
+    if (this.get('isAuthenticated')) {
+      this.get('user').set('url_name', this.get('user.slug') + '-' + this.get('user.id'));
+    }
+  },
+
+  setUserUrlNameOnInit: function() {
+    this.setUrlNameOnUser();
+  }.on('init'),
+
+  syncUrlNameOnUser: function() {
+    this.setUrlNameOnUser();
+  }.observes('user.id', 'user.slug'),
+
   // Return user as POJO
   // Return user as POJO
 
 
   getUserPOJO: function() {
   getUserPOJO: function() {

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

@@ -22,3 +22,5 @@
 
 
 @import "change-avatar.less";
 @import "change-avatar.less";
 @import "user-options.less";
 @import "user-options.less";
+@import "user-profile.less";
+@import "user-status.less";

+ 6 - 0
misago/emberapp/app/styles/misago/page-header.less

@@ -9,6 +9,12 @@
   h1 {
   h1 {
     font-size: @font-size-base * 2;
     font-size: @font-size-base * 2;
   }
   }
+
+  .list-unstyled {
+    .material-icons {
+      top: 0px;
+    }
+  }
 }
 }
 
 
 
 

+ 70 - 0
misago/emberapp/app/styles/misago/user-profile.less

@@ -0,0 +1,70 @@
+//
+// User Profile Page
+// --------------------------------------------------
+
+
+// Profile Header
+.user-page .page-header {
+  .user-avatar {
+    display: none;
+  }
+
+  // Small displays
+  @media (max-width: @screen-sm-max) {
+    padding-top: @line-height-computed - 1px;
+    padding-bottom: @line-height-computed - 7px;
+
+    h1 {
+      margin: 0px;
+
+      .user-avatar {
+        border-radius: @avatar-radius;
+        display: inline-block;
+        vertical-align: middle;
+
+        margin-top: -6px;
+
+        width: 44px;
+        height: 44px;
+      }
+    }
+  }
+}
+
+
+// Profile Sidebar Avatar
+.user-page .side-avatar {
+  background: @body-bg;
+  border: 1px solid @page-header-border-color;
+  border-radius: @avatar-radius + 4px;
+  margin-top: @line-height-computed * -5.5;
+  margin-bottom: @line-height-computed;
+  padding: 4px;
+
+  .user-avatar {
+    border-radius: @avatar-radius;
+    display: block;
+
+    width: 100%;
+    height: auto;
+  }
+}
+
+
+// Profile small display details
+.user-page .profile-sidepanel .list-unstyled {
+  font-size: @font-size-base * 1.5;
+
+  li {
+    margin: 0px 3px;
+  }
+
+  .material-icons {
+    margin-right: @line-height-computed / 3;
+    vertical-align: bottom;
+
+    top: 0px;
+
+    font-size: @font-size-base * 1.5 * 1.5;
+  }
+}

+ 12 - 0
misago/emberapp/app/styles/misago/user-status.less

@@ -0,0 +1,12 @@
+//
+// User Status Styles
+// --------------------------------------------------
+
+
+.user-banned .material-icons {
+  color: @brand-warning;
+}
+
+.user-online .material-icons {
+  color: @brand-success;
+}

+ 13 - 0
misago/emberapp/app/templates/components/user-state-icon.hbs

@@ -0,0 +1,13 @@
+{{#if user.state.is_banned}}
+  <i class="material-icons">remove_circle_outline</i>
+{{else if user.state.is_hidden}}
+  <i class="material-icons">radio_button_unchecked</i>
+{{else if user.state.is_online_hidden}}
+  <i class="material-icons">gps_fixed</i>
+{{else if user.state.is_offline_hidden}}
+  <i class="material-icons">gps_not_fixed</i>
+{{else if user.state.is_online}}
+  <i class="material-icons">radio_button_checked</i>
+{{else if user.state.is_offline}}
+  <i class="material-icons">radio_button_unchecked</i>
+{{/if}}

+ 19 - 0
misago/emberapp/app/templates/components/user-state-label.hbs

@@ -0,0 +1,19 @@
+{{#if user.state.is_banned}}
+  <i class="material-icons">remove_circle_outline</i>
+  {{gettext "Banned"}}
+{{else if user.state.is_hidden}}
+  <i class="material-icons">radio_button_unchecked</i>
+  {{gettext "Hidden"}}
+{{else if user.state.is_online_hidden}}
+  <i class="material-icons">gps_fixed</i>
+  {{gettext "Online, hidden"}}
+{{else if user.state.is_offline_hidden}}
+  <i class="material-icons">gps_not_fixed</i>
+  {{gettext "Seen %(last_seen)s, hidden" last_seen=(from-now lastClick)}}
+{{else if user.state.is_online}}
+  <i class="material-icons">radio_button_checked</i>
+  {{gettext "Online"}}
+{{else if user.state.is_offline}}
+  <i class="material-icons">radio_button_unchecked</i>
+  {{gettext "Seen %(last_seen)s" last_seen=(from-now lastClick)}}
+{{/if}}

+ 56 - 8
misago/emberapp/app/templates/user.hbs

@@ -3,19 +3,67 @@
   <div class="page-header">
   <div class="page-header">
     <div class="container">
     <div class="container">
 
 
-      <div class="media">
-        <div class="media-left">
-          {{user-avatar user=model size=100}}
-        </div>
-        <div class="media-body">
-          <h1 class="media-heading">{{model.username}}</h1>
-          Lorem ipsum dolor met.
+      <div class="row">
+        <div class="col-md-9 col-md-offset-3">
+
+          <h1>
+            {{user-avatar user=model size=100}}
+            {{model.username}}
+          </h1>
+
+          <ul class="list-inline text-muted hidden-xs hidden-sm">
+            <li>
+              <i class="material-icons">group</i>
+              {{model.finalTitle}}
+            </li>
+            {{user-state-label user=model tagName='li'}}
+            {{#if model.email}}
+            <li>
+              <i class="material-icons">email</i>
+              <a href="mailto:{{model.email}}" class="site-link">{{model.email}}</a>
+            </li>
+            {{/if}}
+          </ul>
+
         </div>
         </div>
       </div>
       </div>
 
 
     </div>
     </div>
   </div>
   </div>
 
 
-  {{outlet}}
+  <div class="container">
+    <div class="row">
+      <div class="col-md-3">
+        <div class="profile-sidepanel">
+
+          <div class="side-avatar hidden-xs hidden-sm">
+            {{user-avatar user=model size=400}}
+          </div>
+
+          <ul class="list-unstyled hidden-md hidden-lg">
+            <li>
+              <i class="material-icons">group</i>
+              {{model.finalTitle}}
+            </li>
+            {{user-state-label user=model tagName='li'}}
+            {{#if model.email}}
+            <li>
+              <i class="material-icons">email</i>
+              <a href="mailto:{{model.email}}" class="site-link">{{model.email}}</a>
+            </li>
+            {{/if}}
+          </ul>
+
+        </div>
+      </div>
+      <div class="col-md-9">
+        <div class="profile-outlet">
+
+          {{outlet}}
+
+        </div>
+      </div>
+    </div>
+  </div>
 
 
 </div>
 </div>