basic implementation
This commit is contained in:
parent
b2a57da4b2
commit
2e6ffdaab7
|
@ -24,4 +24,7 @@ coverage/
|
||||||
*~
|
*~
|
||||||
|
|
||||||
# every fucking time, dolphin
|
# every fucking time, dolphin
|
||||||
.directory
|
.directory
|
||||||
|
# lookin' at you, OS trash
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.DB
|
||||||
|
|
1
Gemfile
1
Gemfile
|
@ -79,4 +79,5 @@ group :development, :test do
|
||||||
gem 'simplecov-json', require: false
|
gem 'simplecov-json', require: false
|
||||||
gem 'simplecov-rcov', require: false
|
gem 'simplecov-rcov', require: false
|
||||||
gem 'database_cleaner'
|
gem 'database_cleaner'
|
||||||
|
gem 'better_errors'
|
||||||
end
|
end
|
||||||
|
|
|
@ -46,6 +46,10 @@ GEM
|
||||||
addressable (2.3.8)
|
addressable (2.3.8)
|
||||||
arel (6.0.0)
|
arel (6.0.0)
|
||||||
bcrypt (3.1.10)
|
bcrypt (3.1.10)
|
||||||
|
better_errors (2.1.1)
|
||||||
|
coderay (>= 1.0.0)
|
||||||
|
erubis (>= 2.6.6)
|
||||||
|
rack (>= 0.9.0)
|
||||||
bootstrap-sass (3.2.0.2)
|
bootstrap-sass (3.2.0.2)
|
||||||
sass (~> 3.2)
|
sass (~> 3.2)
|
||||||
bootstrap3-datetimepicker-rails (4.7.14)
|
bootstrap3-datetimepicker-rails (4.7.14)
|
||||||
|
@ -68,6 +72,7 @@ GEM
|
||||||
cliver (0.3.2)
|
cliver (0.3.2)
|
||||||
cocaine (0.5.7)
|
cocaine (0.5.7)
|
||||||
climate_control (>= 0.0.3, < 1.0)
|
climate_control (>= 0.0.3, < 1.0)
|
||||||
|
coderay (1.1.0)
|
||||||
coffee-rails (4.1.0)
|
coffee-rails (4.1.0)
|
||||||
coffee-script (>= 2.2.0)
|
coffee-script (>= 2.2.0)
|
||||||
railties (>= 4.0.0, < 5.0)
|
railties (>= 4.0.0, < 5.0)
|
||||||
|
@ -365,6 +370,7 @@ PLATFORMS
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
bcrypt (~> 3.1.7)
|
bcrypt (~> 3.1.7)
|
||||||
|
better_errors
|
||||||
bootstrap-sass (~> 3.2.0.1)
|
bootstrap-sass (~> 3.2.0.1)
|
||||||
bootstrap3-datetimepicker-rails (~> 4.7.14)
|
bootstrap3-datetimepicker-rails (~> 4.7.14)
|
||||||
bootstrap_form
|
bootstrap_form
|
||||||
|
|
|
@ -48,4 +48,46 @@
|
||||||
|
|
||||||
cropper.attr 'src', e.target.result
|
cropper.attr 'src', e.target.result
|
||||||
|
|
||||||
fr.readAsDataURL(input.files[0])
|
fr.readAsDataURL(input.files[0])
|
||||||
|
|
||||||
|
($ document).on 'change', 'input#user_profile_header[type=file]', ->
|
||||||
|
input = ($ this)[0]
|
||||||
|
|
||||||
|
($ '#profile-header-crop-controls').slideUp 400, ->
|
||||||
|
if input.files and input.files[0]
|
||||||
|
fr = new FileReader()
|
||||||
|
($ fr).on 'load', (e) ->
|
||||||
|
cropper = ($ '#profile-header-cropper')
|
||||||
|
preview = ($ '#profile-header-preview')
|
||||||
|
|
||||||
|
updateVars = (data, action) ->
|
||||||
|
($ '#crop_h_x').val Math.floor(data.x / data.scale)
|
||||||
|
($ '#crop_h_y').val Math.floor(data.y / data.scale)
|
||||||
|
($ '#crop_h_w').val Math.floor(data.w / data.scale)
|
||||||
|
($ '#crop_h_h').val Math.floor(data.h / data.scale)
|
||||||
|
# rx = 100 / data.w
|
||||||
|
# ry = 100 / data.h
|
||||||
|
# ($ '#profile-picture-preview').css
|
||||||
|
# width: Math.round(rx * preview[0].naturalWidth) + 'px'
|
||||||
|
# height: Math.round(ry * preview[0].naturalHeight) + 'px'
|
||||||
|
# marginLeft: '-' + Math.round(rx * data.x) + 'px'
|
||||||
|
# marginTop: '-' + Math.round(ry * data.y) + 'px'
|
||||||
|
|
||||||
|
cropper.on 'load', ->
|
||||||
|
width = 1500
|
||||||
|
height = 500
|
||||||
|
|
||||||
|
cropper.guillotine
|
||||||
|
width: 1500
|
||||||
|
height: 500
|
||||||
|
onChange: updateVars
|
||||||
|
|
||||||
|
updateVars cropper.guillotine('getData'), 'drag' # just because
|
||||||
|
|
||||||
|
($ '#cropper-zoom-out').click -> cropper.guillotine 'zoomOut'
|
||||||
|
($ '#cropper-zoom-in').click -> cropper.guillotine 'zoomIn'
|
||||||
|
($ '#profile-header-crop-controls').slideDown()
|
||||||
|
|
||||||
|
cropper.attr 'src', e.target.result
|
||||||
|
|
||||||
|
fr.readAsDataURL(input.files[0])
|
||||||
|
|
|
@ -28,13 +28,11 @@
|
||||||
margin-top: 0.65em;
|
margin-top: 0.65em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile--header {
|
#profile--header {
|
||||||
position: absolute;
|
position: relative;
|
||||||
z-index: 0;
|
z-index: -1;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 300px;
|
|
||||||
background-color: darken($navbar-inverse-bg, 10%);
|
background-color: darken($navbar-inverse-bg, 10%);
|
||||||
background-size: cover;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile--panel .panel-heading {
|
.profile--panel .panel-heading {
|
||||||
|
@ -100,14 +98,20 @@ $colours: danger $brand-danger,
|
||||||
text-decoration: line-through !important;
|
text-decoration: line-through !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile--panel-push-50 {
|
.profile--panel-push-inner {
|
||||||
display: block;
|
display: block;
|
||||||
height: 50px;
|
height: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile--header-img {
|
||||||
|
display: block;
|
||||||
|
min-width: 900px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile--panel-push-200 {
|
@media(min-width: 767px) {
|
||||||
display: block;
|
.container.headerable {
|
||||||
height: 180px;
|
padding-top: 0;
|
||||||
width: 100%;
|
margin-top: -30px;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -24,11 +24,12 @@ class UserController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
user_attributes = params.require(:user).permit(:display_name, :profile_picture, :motivation_header, :website,
|
user_attributes = params.require(:user).permit(:display_name, :profile_picture, :profile_header, :motivation_header, :website,
|
||||||
:location, :bio, :crop_x, :crop_y, :crop_w, :crop_h)
|
:location, :bio, :crop_x, :crop_y, :crop_w, :crop_h)
|
||||||
if current_user.update_attributes(user_attributes)
|
if current_user.update_attributes(user_attributes)
|
||||||
text = 'Your profile has been updated!'
|
text = 'Your profile has been updated!'
|
||||||
text += ' It might take a few minutes until your new profile picture is shown everywhere.' if user_attributes[:profile_picture]
|
text += ' It might take a few minutes until your new profile picture is shown everywhere.' if user_attributes[:profile_picture]
|
||||||
|
text += ' It might take a few minutes until your new profile header is shown everywhere.' if user_attributes[:profile_header]
|
||||||
flash[:success] = text
|
flash[:success] = text
|
||||||
else
|
else
|
||||||
flash[:error] = 'An error occurred. ;_;'
|
flash[:error] = 'An error occurred. ;_;'
|
||||||
|
|
|
@ -49,7 +49,14 @@ class User < ActiveRecord::Base
|
||||||
default_url: "/images/:style/no_avatar.png", use_timestamp: false,
|
default_url: "/images/:style/no_avatar.png", use_timestamp: false,
|
||||||
processors: [:cropper]
|
processors: [:cropper]
|
||||||
validates_attachment_content_type :profile_picture, :content_type => /\Aimage\/.*\Z/
|
validates_attachment_content_type :profile_picture, :content_type => /\Aimage\/.*\Z/
|
||||||
|
|
||||||
|
has_attached_file :profile_header, styles: { web: "1500x350#", mobile: "450x105#", retina: "900x210#" },
|
||||||
|
default_url: '/images/header/:style/no_header.jpg', use_timestamp: false,
|
||||||
|
processors: [:cropper]
|
||||||
|
validates_attachment_content_type :profile_header, :content_type => /\Aimage\/.*\Z/
|
||||||
|
|
||||||
process_in_background :profile_picture
|
process_in_background :profile_picture
|
||||||
|
process_in_background :profile_header
|
||||||
|
|
||||||
before_save do
|
before_save do
|
||||||
self.display_name = 'WRYYYYYYYY' if display_name == 'Dio Brando'
|
self.display_name = 'WRYYYYYYYY' if display_name == 'Dio Brando'
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
.row#profile-picture-crop-controls{style: 'display: none;'}
|
.row#profile-picture-crop-controls{style: 'display: none;'}
|
||||||
.col-sm-10.col-md-8
|
.col-sm-10.col-md-8
|
||||||
%strong Adjust your new image
|
%strong Adjust your new avatar
|
||||||
%img#profile-picture-cropper{src: current_user.profile_picture.url(:medium)}
|
%img#profile-picture-cropper{src: current_user.profile_picture.url(:medium)}
|
||||||
.col-sm-2.col-md-4
|
.col-sm-2.col-md-4
|
||||||
.btn-group
|
.btn-group
|
||||||
|
@ -25,6 +25,23 @@
|
||||||
%button#cropper-zoom-in.btn.btn-inverse{type: :button}
|
%button#cropper-zoom-in.btn.btn-inverse{type: :button}
|
||||||
%i.fa.fa-search-plus
|
%i.fa.fa-search-plus
|
||||||
|
|
||||||
|
.media
|
||||||
|
.pull-left
|
||||||
|
%img.img-rounded.header--img{src: current_user.profile_header.url(:mobile)}
|
||||||
|
.media-body
|
||||||
|
= f.file_field :profile_header
|
||||||
|
|
||||||
|
.row#profile-header-crop-controls{style: 'display: none;'}
|
||||||
|
.col-sm-10.col-md-8
|
||||||
|
%strong Adjust your new header
|
||||||
|
%img#profile-header-cropper{src: current_user.profile_header.url(:web)}
|
||||||
|
.col-sm-2.col-md-4
|
||||||
|
.btn-group
|
||||||
|
%button#cropper-zoom-out.btn.btn-inverse{type: :button}
|
||||||
|
%i.fa.fa-search-minus
|
||||||
|
%button#cropper-zoom-in.btn.btn-inverse{type: :button}
|
||||||
|
%i.fa.fa-search-plus
|
||||||
|
|
||||||
= f.text_field :motivation_header, label: "Motivation header", placeholder: 'Ask me anything!'
|
= f.text_field :motivation_header, label: "Motivation header", placeholder: 'Ask me anything!'
|
||||||
|
|
||||||
= f.text_field :website, label: "Website", placeholder: 'http://example.com'
|
= f.text_field :website, label: "Website", placeholder: 'http://example.com'
|
||||||
|
@ -36,4 +53,7 @@
|
||||||
- for attrib in %i(crop_x crop_y crop_w crop_h)
|
- for attrib in %i(crop_x crop_y crop_w crop_h)
|
||||||
= f.hidden_field attrib, id: attrib
|
= f.hidden_field attrib, id: attrib
|
||||||
|
|
||||||
= f.submit "Save settings", class: 'btn btn-primary'
|
- for attrib in %i(crop_h_x crop_h_y crop_h_w crop_h_h)
|
||||||
|
= f.hidden_field attrib, id: attrib
|
||||||
|
|
||||||
|
= f.submit "Save settings", class: 'btn btn-primary'
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
.profile--header
|
#profile--header.hidden-xs
|
||||||
.container.j2-page
|
%img.profile--header-img{src: current_user.profile_header.url(:web)}
|
||||||
|
#profile--panel-push-n.hidden-xs
|
||||||
|
.container.j2-page.headerable
|
||||||
.col-md-3.col-xs-12.col-sm-4.j2-col-reset
|
.col-md-3.col-xs-12.col-sm-4.j2-col-reset
|
||||||
= render 'user/profile_info'
|
= render 'user/profile_info'
|
||||||
.hidden-xs= render 'shared/links'
|
.hidden-xs= render 'shared/links'
|
||||||
.col-md-9.col-xs-12.col-sm-8.j2-col-reset
|
.col-md-9.col-xs-12.col-sm-8.j2-col-reset
|
||||||
.profile--panel-push-200.hidden-xs
|
.profile--panel-push-inner.hidden-xs
|
||||||
= render 'shared/questionbox'
|
= render 'shared/questionbox'
|
||||||
- unless @user.banned?
|
- unless @user.banned?
|
||||||
#answers
|
#answers
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
class AddAttachmentProfileHeaderToUsers < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
change_table :users do |t|
|
||||||
|
t.attachment :profile_header
|
||||||
|
t.boolean :profile_header_processing
|
||||||
|
t.integer :crop_h_x
|
||||||
|
t.integer :crop_h_y
|
||||||
|
t.integer :crop_h_w
|
||||||
|
t.integer :crop_h_h
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
28
db/schema.rb
28
db/schema.rb
|
@ -11,7 +11,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 20150422024104) do
|
ActiveRecord::Schema.define(version: 20150508144336) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
@ -28,12 +28,24 @@ ActiveRecord::Schema.define(version: 20150422024104) do
|
||||||
|
|
||||||
add_index "answers", ["user_id", "created_at"], name: "index_answers_on_user_id_and_created_at", using: :btree
|
add_index "answers", ["user_id", "created_at"], name: "index_answers_on_user_id_and_created_at", using: :btree
|
||||||
|
|
||||||
|
create_table "comment_smiles", force: :cascade do |t|
|
||||||
|
t.integer "user_id"
|
||||||
|
t.integer "comment_id"
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.datetime "updated_at", null: false
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index "comment_smiles", ["comment_id"], name: "index_comment_smiles_on_comment_id", using: :btree
|
||||||
|
add_index "comment_smiles", ["user_id", "comment_id"], name: "index_comment_smiles_on_user_id_and_comment_id", unique: true, using: :btree
|
||||||
|
add_index "comment_smiles", ["user_id"], name: "index_comment_smiles_on_user_id", using: :btree
|
||||||
|
|
||||||
create_table "comments", force: :cascade do |t|
|
create_table "comments", force: :cascade do |t|
|
||||||
t.string "content"
|
t.string "content"
|
||||||
t.integer "answer_id"
|
t.integer "answer_id"
|
||||||
t.integer "user_id"
|
t.integer "user_id"
|
||||||
t.datetime "created_at"
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at"
|
t.datetime "updated_at"
|
||||||
|
t.integer "smile_count", default: 0, null: false
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "comments", ["user_id", "created_at"], name: "index_comments_on_user_id_and_created_at", using: :btree
|
add_index "comments", ["user_id", "created_at"], name: "index_comments_on_user_id_and_created_at", using: :btree
|
||||||
|
@ -206,9 +218,21 @@ ActiveRecord::Schema.define(version: 20150422024104) do
|
||||||
t.boolean "privacy_allow_public_timeline", default: true
|
t.boolean "privacy_allow_public_timeline", default: true
|
||||||
t.boolean "privacy_allow_stranger_answers", default: true
|
t.boolean "privacy_allow_stranger_answers", default: true
|
||||||
t.boolean "privacy_show_in_search", default: true
|
t.boolean "privacy_show_in_search", default: true
|
||||||
t.boolean "banned", default: false
|
t.boolean "permanently_banned", default: false
|
||||||
t.boolean "blogger", default: false
|
t.boolean "blogger", default: false
|
||||||
t.boolean "contributor", default: false
|
t.boolean "contributor", default: false
|
||||||
|
t.string "ban_reason"
|
||||||
|
t.datetime "banned_until"
|
||||||
|
t.integer "comment_smiled_count", default: 0, null: false
|
||||||
|
t.string "profile_header_file_name"
|
||||||
|
t.string "profile_header_content_type"
|
||||||
|
t.integer "profile_header_file_size"
|
||||||
|
t.datetime "profile_header_updated_at"
|
||||||
|
t.boolean "profile_header_processing"
|
||||||
|
t.integer "crop_h_x"
|
||||||
|
t.integer "crop_h_y"
|
||||||
|
t.integer "crop_h_w"
|
||||||
|
t.integer "crop_h_h"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
|
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 886 B |
Binary file not shown.
After Width: | Height: | Size: 9.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
Binary file not shown.
After Width: | Height: | Size: 6.3 KiB |
Loading…
Reference in New Issue