From 5ae54f9e364880e1350ddcc8251a23cf79ae55fc Mon Sep 17 00:00:00 2001
From: Eugen Rochko <eugen@zeonfederated.com>
Date: Sun, 28 Feb 2016 00:51:05 +0100
Subject: [PATCH] Adding avatars to profile page and statuses

---
 .gitignore                              |   1 +
 app/assets/images/avatars/missing.png   | Bin 0 -> 3890 bytes
 app/assets/stylesheets/application.scss |  13 +++++
 app/assets/stylesheets/profile.scss     |  62 ++++++++++++++++--------
 app/models/account.rb                   |   8 ++-
 app/views/profile/_status.html.haml     |  16 +++---
 app/views/profile/show.html.haml        |  12 +++--
 7 files changed, 81 insertions(+), 31 deletions(-)
 create mode 100644 app/assets/images/avatars/missing.png

diff --git a/.gitignore b/.gitignore
index 6d3b796529..b4a53fe1bf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,3 +16,4 @@
 !/log/.keep
 /tmp
 coverage
+public/system
diff --git a/app/assets/images/avatars/missing.png b/app/assets/images/avatars/missing.png
new file mode 100644
index 0000000000000000000000000000000000000000..40353039fd4c94c018d765c97bcd935fd0307a88
GIT binary patch
literal 3890
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

literal 0
HcmV?d00001

diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss
index 91b0d12fe7..068480994b 100644
--- a/app/assets/stylesheets/application.scss
+++ b/app/assets/stylesheets/application.scss
@@ -14,11 +14,24 @@ body {
   font-size: 13px;
   line-height: 18px;
   color: $quaternary-color;
+
+  &::before {
+    display: block;
+    content: "";
+    position: absolute;
+    background: $secondary-color;
+    width: 100%;
+    height: 200px;
+    z-index: -1;
+    top: 0;
+    left: 0;
+  }
 }
 
 .container {
   width: 800px;
   margin: 0 auto;
+  z-index: 2;
 }
 
 .footer {
diff --git a/app/assets/stylesheets/profile.scss b/app/assets/stylesheets/profile.scss
index 5508b84247..e2b59268ae 100644
--- a/app/assets/stylesheets/profile.scss
+++ b/app/assets/stylesheets/profile.scss
@@ -1,5 +1,13 @@
 .card {
-  padding-top: 20px;
+  margin-top: 40px;
+  display: flex;
+  background: darken($background-color, 10%);
+  border-bottom: 1px solid darken($background-color, 15%);
+  box-shadow: 4px 3px 0 rgba(0, 0, 0, 0.1);
+
+  .bio {
+    flex-grow: 1;
+  }
 
   .name {
     font-size: 24px;
@@ -12,24 +20,18 @@
     }
   }
 
-  .bio {
-
-  }
-
-  .counter {
-    display: block;
+  .avatar {
+    width: 96px;
     float: left;
-    width: 100px;
-    text-align: center;
-    border: 1px solid #A593E0;
-    color: #A593E0;
-    border-radius: 5px;
-    padding: 3px 0;
-    margin-right: 3px;
-
-    .num {
+    margin-right: 10px;
+    padding: 10px;
+    margin-top: -30px;
+
+    img {
+      width: 94px;
+      height: 94px;
       display: block;
-      font-size: 24px;
+      border: 2px solid $background-color;
     }
   }
 }
@@ -52,11 +54,33 @@
     }
   }
 
+  .entry-container {
+    display: flex;
+  }
+
+  .avatar {
+    width: 48px;
+    padding: 10px;
+    padding-left: 8px;
+    padding-right: 0;
+    padding-top: 12px;
+
+    img {
+      width: 48px;
+      height: 48px;
+      display: block;
+      box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.1);
+    }
+  }
+
+  .container {
+    flex-grow: 1;
+  }
+
   .header {
     margin-bottom: 10px;
     padding: 10px;
     padding-bottom: 0;
-    padding-left: 8px;
 
     .name {
       text-decoration: none;
@@ -79,6 +103,7 @@
     color: $tertiary-color;
     padding: 5px 10px;
     padding-left: 8px;
+    clear: both;
 
     .name {
       color: $tertiary-color;
@@ -112,7 +137,6 @@
     cursor: default;
     padding: 10px;
     padding-top: 0;
-    padding-left: 8px;
 
     .counter {
       display: inline-block;
diff --git a/app/models/account.rb b/app/models/account.rb
index 0940118dcf..f1ac6fdd76 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -3,7 +3,8 @@ class Account < ActiveRecord::Base
   has_one :user, inverse_of: :account
 
   # Avatar upload
-  has_attached_file :avatar, styles: { large: '300x300#', medium: '96x96#', small: '48x48#' }
+  attr_reader :avatar_remote_url
+  has_attached_file :avatar, styles: { large: '300x300#', medium: '96x96#', small: '48x48#' }, default_url: 'avatars/missing.png'
   validates_attachment_content_type :avatar, content_type: /\Aimage\/.*\Z/
 
   # Timelines
@@ -64,6 +65,11 @@ class Account < ActiveRecord::Base
     @subscription ||= OStatus2::Subscription.new(self.remote_url, secret: self.secret, token: self.verify_token, webhook: webhook_url, hub: self.hub_url)
   end
 
+  def avatar_remote_url=(url)
+    self.avatar = URI.parse(url)
+    @avatar_remote_url = url
+  end
+
   before_create do
     if local?
       keypair = OpenSSL::PKey::RSA.new(Rails.env.test? ? 48 : 2048)
diff --git a/app/views/profile/_status.html.haml b/app/views/profile/_status.html.haml
index 44c58b84e5..c2033b4f73 100644
--- a/app/views/profile/_status.html.haml
+++ b/app/views/profile/_status.html.haml
@@ -4,9 +4,13 @@
       %i.fa.fa-retweet
       Shared by
       = link_to display_name(status.account), profile_url(status.account), class: 'name'
-  .header
-    = render partial: 'status_header', locals: { status: status.reblog? ? status.reblog : status }
-  .content
-    = status.content
-  .counters
-    = render partial: 'status_footer', locals: { status: status.reblog? ? status.reblog : status }
+  .entry-container
+    .avatar
+      = image_tag status.reblog? ? status.reblog.account.avatar.url(:small) : status.account.avatar.url(:small)
+    .container
+      .header
+        = render partial: 'status_header', locals: { status: status.reblog? ? status.reblog : status }
+      .content
+        = status.content
+      .counters
+        = render partial: 'status_footer', locals: { status: status.reblog? ? status.reblog : status }
diff --git a/app/views/profile/show.html.haml b/app/views/profile/show.html.haml
index c84cb7e817..b93791734c 100644
--- a/app/views/profile/show.html.haml
+++ b/app/views/profile/show.html.haml
@@ -1,8 +1,10 @@
-%div.card
-  %h1.name
-    = @account.display_name.blank? ? @account.username : @account.display_name
-    %small= "@#{@account.username}"
+.card
+  .avatar= image_tag @account.avatar.url(:medium)
+  .bio
+    %h1.name
+      = @account.display_name.blank? ? @account.username : @account.display_name
+      %small= "@#{@account.username}"
 
-%div.activity-stream
+.activity-stream
   - @account.statuses.order('id desc').each do |status|
     = render partial: 'status', locals: { status: status }
-- 
GitLab