Skip to content

Instantly share code, notes, and snippets.

@secretpray
Last active March 15, 2023 18:31
Show Gist options
  • Save secretpray/275912745160ee676c9d90eac635be2e to your computer and use it in GitHub Desktop.
Save secretpray/275912745160ee676c9d90eac635be2e to your computer and use it in GitHub Desktop.
Modded gravatar for User model (Tailwind 2.x)
  1. Gemfile (bundle install)
```ruby
gem 'faker', :git => 'https://github.com/faker-ruby/faker.git', :branch => 'master' # optional!!! (only for use in seed.rb)
gem 'faraday' # optional!!! (only for use in seed.rb)
gem 'gravatar_image_tag', github: 'secretpray/gravatar_image_tag', branch: 'master'
gem 'hotwire-rails' # optional!!!
gem 'image_processing', '~> 1.2'
gem 'tailwindcss-rails', '~> 0.5.1' # optional!!!
```

2) Sample view template
~~~~~~~~~~~~~~~~~~~~~~~
```
<span class='text-gray-400 transform transition duration-300 hover:scale-110 cursor-pointer'>
  <%= link_to account_path(current_user), data: { turbo: "false" } do %>
    <%= user_avatar(current_user, 40) %>
  <% end %>
</span>
```

PS To use current_user check for installed gem Devise with model User and Active Storage!!!

3) app/helpers/users_helper.rb
module UsersHelper
  def user_avatar(user, size=40)
    # if user.avatar.attached?
    if user.respond_to?(:avatar) && user.avatar.attached? && user.avatar.variable?
      image_tag user.avatar.variant(resize: "#{size}x#{size}!"), class: 'rounded-full'
    else
      avatar_circle(user, size)
      # gravatar_image_url(user.email, size: size)
    end
  end

  def avatar_circle(user, size)
    if gravatar_exists?(user.email)
      image_tag gravatar_image_url(user.email, size: size), class: 'rounded-full'
      # gravatar_id = Digest::MD5.hexdigest(user.email)
      # gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}"
      # image_tag(gravatar_url, class: 'avatar_circle')
    else
      # inline_svg_pack_tag('media/images/user.svg', class: "rounded", size: "5rem * 5rem")
      initials = [user.first_name&.first, user.last_name&.first].join('')
      initials = user.email.gsub(/[[-.][_.]]+/, '').first(2) if initials.blank?
      style = "background-color: #{avatar_color(initials)}; height: #{size}px; width: #{size}px;"
      content_tag :div, class: 'avatar-circle', style: style do
        content_tag :div, initials, class: 'avatar-text'
      end
    end
  end

  def gravatar_exists?(email)
    hash = Digest::MD5.hexdigest(email)
    http = Net::HTTP.new('www.gravatar.com', 80)
    http.read_timeout = 2
    response = http.request_head("/avatar/#{hash}?default=http://gravatar.com/avatar")
    response.code != '302' ? true : false
  rescue StandardError, Timeout::Error
    false
  end

  def avatar_color(initials)
    colors = [
      '#00AA55', '#009FD4', '#B381B3', '#939393', '#E3BC00',
      '#047500', '#DC2A2A', '#696969', '#ff0000', '#ff80ed',
      '#407294', '#133337', '#065535', '#c0c0c0', '#5ac18e',
      '#666666', '#f7347a', '#576675', '#696966', '#008080',
      '#ffa500', '#40e0d0', '#8000ff', '#003366', '#fa8072',
      '#800000'
    ]

    colors[initials.first.to_s.downcase.ord - 97] || '#000000'
  end

end
  1. app/models/user.rb
```ruby
class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

  has_one_attached :avatar
end
```

5) app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected

  def configure_permitted_parameters
    added_attrs = [:avatar]
    devise_parameter_sanitizer.permit(:sign_up, keys: added_attrs)
    devise_parameter_sanitizer.permit(:account_update, keys: added_attrs)
  end

end
  1. app/assets/stylesheets/user.scss
```html
.avatar-circle {
  display: inline-block;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  position: relative;
}

.avatar-text {
  color: #fff;
  text-transform: uppercase;
  transform: translate(-50%, -50%);
  left: 50%;
  top: 50%;
  position: absolute;
}
```
_ Optional part _
db/seeds.rb
~~~~~~~~~~~
```ruby
require 'open-uri'
require 'faraday'
require 'json'

Post.destroy_all
User.destroy_all

DEFAULT_MALE_IMAGE_URL = 'https://randomuser.me/api/portraits/men/43.jpg'
DEFAULT_FEMALE_IMAGE_URL = 'https://randomuser.me/api/portraits/women/49.jpg'
MAX_MALES = 7
MAX_FEMALES = 8

puts 'Please wait while get seed data!'
admin = User.where(email: '[email protected]', first_name: 'Aleksey', last_name: 'Reznov').first_or_initialize
admin.update(password: 'password') if admin.new_record?

# Star Wars heroes
response = Faraday.get('https://akabab.github.io/starwars-api/api/all.json')
data = JSON.parse(response.body)
# sleep 1
males, females = data.partition { |hero| hero['gender'] == 'male' }
males = males.sample(MAX_MALES) # limit users => 15
females = females.sample(MAX_FEMALES)

def set_email(hero)
  "#{hero['name'].parameterize.underscore}@starwars.com"
end

def set_url(gender)
  gender == 'male' ? DEFAULT_MALE_IMAGE_URL : DEFAULT_FEMALE_IMAGE_URL
end

def create_avatar(user, gender, url = nil)
  url = set_url(gender) if url.nil?
  downloaded_image = URI.parse(url).open rescue nil # check bad image URL: "[email protected]" - 404
  if downloaded_image.nil?
    downloaded_image = URI.parse(set_url(gender)).open rescue nil
  end
  return if downloaded_image.nil?

  user.avatar.attach(io: downloaded_image, filename: user.email)
end

def create_user(hero)
  hero_email = set_email(hero)
  first_name_hero, *last_name_hero = hero['name'].split(' ')
  last_name_hero = last_name_hero.join(' ') if last_name_hero.is_a?(Array)
  user = User.create!(email: hero_email,
                      first_name: first_name_hero,
                      last_name: last_name_hero,
                      password: 'password')
  create_avatar(user, hero['gender'], hero['image'])
  print('.')
end

print "Create users."
males.each   { |hero| create_user(hero) }
females.each { |hero| create_user(hero) }

puts "All Ok!"
puts "Created #{User.count} users!"
```
@secretpray
Copy link
Author

secretpray commented Mar 15, 2023

def drawable
    data = drawing_params[:drawable]
    data = data.split(',')[1]
    data = Base64.decode64(data)

    file = Tempfile.new(['image', '.png'])
    file.binmode
    file.write(data)
    file.rewind

    @drawing = Drawing.find(params[:id])
    @drawing.image.attach(io: file, filename: 'image.png')
    file.unlink
  end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment