diff --git a/Gemfile b/Gemfile index 2a05e06d55..ee817a0c46 100644 --- a/Gemfile +++ b/Gemfile @@ -21,6 +21,7 @@ gem 'grape-route-helpers' gem 'grape-entity' gem 'hashie-forbidden_attributes' gem 'paranoia', '~> 2.0' +gem 'paperclip', '~> 4.3' gem 'http' gem 'addressable' diff --git a/Gemfile.lock b/Gemfile.lock index 70b73e87c0..c83a5abb16 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -50,6 +50,10 @@ GEM binding_of_caller (0.7.2) debug_inspector (>= 0.0.1) builder (3.2.2) + climate_control (0.0.3) + activesupport (>= 3.0) + cocaine (0.5.8) + climate_control (>= 0.0.3, < 1.0) coderay (1.1.1) coercible (1.0.0) descendants_tracker (~> 0.0.1) @@ -146,6 +150,7 @@ GEM mime-types (>= 1.16, < 3) method_source (0.8.2) mime-types (2.99) + mimemagic (0.3.0) mini_portile2 (2.0.0) minitest (5.8.4) multi_json (1.11.2) @@ -158,6 +163,12 @@ GEM addressable (~> 2.4) http (~> 1.0) nokogiri (~> 1.6) + paperclip (4.3.5) + activemodel (>= 3.2.0) + activesupport (>= 3.2.0) + cocaine (~> 0.5.5) + mime-types + mimemagic (= 0.3.0) paranoia (2.1.5) activerecord (~> 4.0) parser (2.3.0.6) @@ -320,6 +331,7 @@ DEPENDENCIES nokogiri nyan-cat-formatter ostatus2 + paperclip (~> 4.3) paranoia (~> 2.0) pg pry-rails diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css deleted file mode 100644 index f9cd5b3483..0000000000 --- a/app/assets/stylesheets/application.css +++ /dev/null @@ -1,15 +0,0 @@ -/* - * This is a manifest file that'll be compiled into application.css, which will include all the files - * listed below. - * - * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, - * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path. - * - * You're free to add application-wide styles to this file and they'll appear at the bottom of the - * compiled file so the styles you add here take precedence over styles defined in any styles - * defined in the other CSS/SCSS files in this directory. It is generally better to create a new - * file per style scope. - * - *= require_tree . - *= require_self - */ diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss new file mode 100644 index 0000000000..91b0d12fe7 --- /dev/null +++ b/app/assets/stylesheets/application.scss @@ -0,0 +1,39 @@ +$primary-color: #ff7473; +$secondary-color: #ffc952; +$tertiary-color: #47b8e0; +$quaternary-color: #34314c; +$background-color: #fff; + +@import url("https://fonts.googleapis.com/css?family=Noto+Sans:400,700,400italic"); +@import "font-awesome-sprockets"; +@import "font-awesome"; + +body { + font-family: 'Noto Sans', sans-serif; + background: $secondary-color; + font-size: 13px; + line-height: 18px; + color: $quaternary-color; +} + +.container { + width: 800px; + margin: 0 auto; +} + +.footer { + text-align: center; + padding: 100px 0; + font-size: 12px; + color: lighten($quaternary-color, 15%); + + .mastodon-link { + color: $quaternary-color; + text-decoration: none; + font-weight: bold; + } +} + + +@import 'home'; +@import 'profile'; diff --git a/app/assets/stylesheets/home.scss b/app/assets/stylesheets/home.scss index 7c3dbfc31f..e69de29bb2 100644 --- a/app/assets/stylesheets/home.scss +++ b/app/assets/stylesheets/home.scss @@ -1,10 +0,0 @@ -.footer { - text-align: center; - padding: 100px 0; - - .mastodon-link { - color: #566270; - text-decoration: none; - font-size: 16px; - } -} diff --git a/app/assets/stylesheets/profile.scss b/app/assets/stylesheets/profile.scss index 3ef4888822..5508b84247 100644 --- a/app/assets/stylesheets/profile.scss +++ b/app/assets/stylesheets/profile.scss @@ -1,20 +1,3 @@ -@import url(https://fonts.googleapis.com/css?family=Noto+Sans:400,700,400italic); - -@import "font-awesome-sprockets"; -@import "font-awesome"; - -body { - font-family: 'Noto Sans', sans-serif; - background: #E0E3DA; - font-size: 13px; - line-height: 18px; -} - -.container { - width: 800px; - margin: 0 auto; -} - .card { padding-top: 20px; @@ -25,7 +8,7 @@ body { small { display: block; font-size: 14px; - color: #566270; + color: lighten($quaternary-color, 15%); } } @@ -56,12 +39,12 @@ body { box-shadow: 4px 3px 0 rgba(0, 0, 0, 0.1); .entry { - border-bottom: 1px solid #E0E3DA; - background: #FFFFF3; - border-left: 2px solid #A593E0; + border-bottom: 1px solid darken($background-color, 10%); + background: $background-color; + border-left: 2px solid $primary-color; &.entry-reblog { - border-left: 2px solid #566270; + border-left: 2px solid $tertiary-color; } &:last-child { @@ -77,10 +60,10 @@ body { .name { text-decoration: none; - color: #566270; + color: lighten($quaternary-color, 15%); strong { - color: #000; + color: $quaternary-color; } &:hover { @@ -92,13 +75,13 @@ body { } .pre-header { - border-bottom: 1px solid #E0E3DA; - color: #566270; + border-bottom: 1px solid darken($background-color, 10%); + color: $tertiary-color; padding: 5px 10px; padding-left: 8px; .name { - color: #566270; + color: $tertiary-color; font-weight: bold; text-decoration: none; @@ -116,7 +99,7 @@ body { .time { text-decoration: none; - color: #566270; + color: lighten($quaternary-color, 15%); &:hover { text-decoration: underline; @@ -125,7 +108,7 @@ body { .counters { margin-top: 15px; - color: #566270; + color: lighten($quaternary-color, 15%); cursor: default; padding: 10px; padding-top: 0; @@ -134,10 +117,11 @@ body { .counter { display: inline-block; margin-right: 10px; + color: lighten($quaternary-color, 50%); } .conversation-link { - color: #A593E0; + color: $primary-color; text-decoration: underline; float: right; } diff --git a/app/helpers/profile_helper.rb b/app/helpers/profile_helper.rb index 5a0d6b31f8..2abe67635f 100644 --- a/app/helpers/profile_helper.rb +++ b/app/helpers/profile_helper.rb @@ -1,2 +1,13 @@ module ProfileHelper + def display_name(account) + account.display_name.blank? ? account.username : account.display_name + end + + def profile_url(account) + account.local? ? super(name: account.username) : account.url + end + + def status_url(status) + status.local? ? super(name: status.account.username, id: status.stream_entry.id) : status.url + end end diff --git a/app/models/account.rb b/app/models/account.rb index 1b4f4ebdf9..0940118dcf 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -2,6 +2,10 @@ class Account < ActiveRecord::Base # Local users has_one :user, inverse_of: :account + # Avatar upload + has_attached_file :avatar, styles: { large: '300x300#', medium: '96x96#', small: '48x48#' } + validates_attachment_content_type :avatar, content_type: /\Aimage\/.*\Z/ + # Timelines has_many :stream_entries, inverse_of: :account has_many :statuses, inverse_of: :account diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index e8a9329c37..c654b5f193 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -10,4 +10,5 @@ .container = yield .footer + Powered by = link_to 'Mastodon', 'https://github.com/Gargron/mastodon', class: 'mastodon-link' diff --git a/app/views/profile/_status.html.haml b/app/views/profile/_status.html.haml index 91c4fad263..44c58b84e5 100644 --- a/app/views/profile/_status.html.haml +++ b/app/views/profile/_status.html.haml @@ -3,7 +3,7 @@ .pre-header %i.fa.fa-retweet Shared by - = link_to status.account.display_name.blank? ? status.account.username : status.account.display_name, (status.account.local? ? profile_url(name: status.account.username) : status.account.url), class: 'name' + = 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 diff --git a/app/views/profile/_status_footer.html.haml b/app/views/profile/_status_footer.html.haml index f29abf27b0..817d19a681 100644 --- a/app/views/profile/_status_footer.html.haml +++ b/app/views/profile/_status_footer.html.haml @@ -1,4 +1,4 @@ -.counter.counter-retweets +.counter.counter-reblogs %i.fa.fa-retweet %span.num= status.reblogs.count @@ -7,4 +7,4 @@ %span.num= status.favourites.count - if status.reply? - = link_to 'View conversation', status.thread.local? ? status_url(name: status.thread.account.username, id: status.thread.id) : status.thread.url, class: 'conversation-link' + = link_to 'View conversation', status_url(status.thread), class: 'conversation-link' diff --git a/app/views/profile/_status_header.html.haml b/app/views/profile/_status_header.html.haml index 6f0e8748ec..e1c8100884 100644 --- a/app/views/profile/_status_header.html.haml +++ b/app/views/profile/_status_header.html.haml @@ -1,8 +1,8 @@ -= link_to (status.account.local? ? profile_url(name: status.account.username) : status.account.url), class: 'name' do - %strong= status.account.display_name.blank? ? status.account.username : status.account.display_name += link_to profile_url(status.account), class: 'name' do + %strong= display_name(status.account) = "@#{status.account.acct}" -= link_to status.local? ? status_url(name: status.account.username, id: status.stream_entry.id) : status.url, class: 'time' do += link_to status_url(status), class: 'time' do %span{ title: status.created_at } = time_ago_in_words(status.created_at) ago diff --git a/db/migrate/20160227230233_add_attachment_avatar_to_accounts.rb b/db/migrate/20160227230233_add_attachment_avatar_to_accounts.rb new file mode 100644 index 0000000000..99d88e5ecf --- /dev/null +++ b/db/migrate/20160227230233_add_attachment_avatar_to_accounts.rb @@ -0,0 +1,11 @@ +class AddAttachmentAvatarToAccounts < ActiveRecord::Migration + def self.up + change_table :accounts do |t| + t.attachment :avatar + end + end + + def self.down + remove_attachment :accounts, :avatar + end +end diff --git a/db/schema.rb b/db/schema.rb index 7eb560d96c..122489b5ed 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,27 +11,31 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160224223247) do +ActiveRecord::Schema.define(version: 20160227230233) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" create_table "accounts", force: :cascade do |t| - t.string "username", default: "", null: false + t.string "username", default: "", null: false t.string "domain" - t.string "verify_token", default: "", null: false - t.string "secret", default: "", null: false + t.string "verify_token", default: "", null: false + t.string "secret", default: "", null: false t.text "private_key" - t.text "public_key", default: "", null: false - t.string "remote_url", default: "", null: false - t.string "salmon_url", default: "", null: false - t.string "hub_url", default: "", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.text "note", default: "", null: false - t.string "display_name", default: "", null: false - t.string "uri", default: "", null: false + t.text "public_key", default: "", null: false + t.string "remote_url", default: "", null: false + t.string "salmon_url", default: "", null: false + t.string "hub_url", default: "", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.text "note", default: "", null: false + t.string "display_name", default: "", null: false + t.string "uri", default: "", null: false t.string "url" + t.string "avatar_file_name" + t.string "avatar_content_type" + t.integer "avatar_file_size" + t.datetime "avatar_updated_at" end add_index "accounts", ["username", "domain"], name: "index_accounts_on_username_and_domain", unique: true, using: :btree