Refactor classified listing social previews (#7679)
* Refactor classified listing social previews * Rename decorator method * Fix overeager renaming
This commit is contained in:
parent
caccdba9ac
commit
7e6c2b3977
11 changed files with 138 additions and 33 deletions
|
|
@ -9,7 +9,8 @@ class SocialPreviewsController < ApplicationController
|
|||
not_found unless @article.published
|
||||
|
||||
template = @article.tags.
|
||||
where("tags.social_preview_template IS NOT NULL AND tags.social_preview_template != ?", "article").
|
||||
where.not(social_preview_template: nil).
|
||||
where.not(social_preview_template: "article").
|
||||
select(:social_preview_template).first&.social_preview_template
|
||||
|
||||
# make sure that the template exists
|
||||
|
|
@ -25,8 +26,7 @@ class SocialPreviewsController < ApplicationController
|
|||
end
|
||||
|
||||
def listing
|
||||
@listing = ClassifiedListing.find(params[:id])
|
||||
define_categories
|
||||
@listing = ClassifiedListing.find(params[:id]).decorate
|
||||
set_respond
|
||||
end
|
||||
|
||||
|
|
@ -51,25 +51,6 @@ class SocialPreviewsController < ApplicationController
|
|||
|
||||
private
|
||||
|
||||
# TODO: [thepracticaldev/oss] don't hardcode this
|
||||
def define_categories
|
||||
cat_info = {
|
||||
"collabs": ["Collaborators Wanted", "#5AE8D9"],
|
||||
"cfp": ["Call For Proposal", "#f58f8d"],
|
||||
"forhire": ["Available For Hire", "#b78cf4"],
|
||||
"education": ["Education", "#5AABE8"],
|
||||
"jobs": ["Now Hiring", "#53c3ad"],
|
||||
"mentors": ["Offering Mentorship", "#A69EE8"],
|
||||
"mentees": ["Looking For Mentorship", "#88aedb"],
|
||||
"forsale": ["Stuff For Sale", "#d0adfb"],
|
||||
"events": ["Upcoming Event", "#f8b3d0"],
|
||||
"misc": ["Miscellaneous", "#6393FF"],
|
||||
"products": ["Products & Tools", "#5AE8D9"]
|
||||
}
|
||||
@category = cat_info[@listing.category.to_sym][0]
|
||||
@cat_color = cat_info[@listing.category.to_sym][1]
|
||||
end
|
||||
|
||||
def set_respond(template = nil)
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ class ClassifiedListingCategoryDashboard < Administrate::BaseDashboard
|
|||
name: Field::String,
|
||||
rules: Field::String,
|
||||
slug: Field::String,
|
||||
social_preview_description: Field::String,
|
||||
social_preview_color: Field::String,
|
||||
updated_at: Field::DateTime
|
||||
}.freeze
|
||||
|
||||
|
|
|
|||
14
app/decorators/classified_listing_decorator.rb
Normal file
14
app/decorators/classified_listing_decorator.rb
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
class ClassifiedListingDecorator < ApplicationDecorator
|
||||
DEFAULT_COLOR = "#000000".freeze
|
||||
|
||||
def social_preview_category
|
||||
category = object.classified_listing_category
|
||||
category.social_preview_description.presence || category.name
|
||||
end
|
||||
|
||||
def social_preview_color(brightness: 1.0)
|
||||
category = object.classified_listing_category
|
||||
color = category.social_preview_color.presence || DEFAULT_COLOR
|
||||
HexComparer.new([color]).brightness(brightness)
|
||||
end
|
||||
end
|
||||
|
|
@ -1,6 +1,21 @@
|
|||
class ClassifiedListingCategory < ApplicationRecord
|
||||
has_many :classified_listings
|
||||
|
||||
before_validation :normalize_social_preview_color
|
||||
|
||||
validates :name, :cost, :rules, :slug, presence: true
|
||||
validates :name, :slug, uniqueness: true
|
||||
|
||||
# This needs to be a hex color of format "#CCC" or "#A1B2C3"
|
||||
validates :social_preview_color,
|
||||
format: /\A#(?:[a-f0-9]{3}){1,2}\z/,
|
||||
allow_blank: true
|
||||
|
||||
private
|
||||
|
||||
def normalize_social_preview_color
|
||||
return unless social_preview_color
|
||||
|
||||
self.social_preview_color = social_preview_color.downcase
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
}
|
||||
|
||||
h1 {
|
||||
color: <%= HexComparer.new([@cat_color]).brightness(0.70) %>;
|
||||
color: <%= @listing.social_preview_color(brightness: 0.70) %>;
|
||||
width: 92%;
|
||||
margin: 0;
|
||||
padding: 1vw;
|
||||
|
|
@ -46,7 +46,7 @@
|
|||
font-size: 3.1vw;
|
||||
padding: 0 4vw;
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", "Roboto", sans-serif;
|
||||
color: <%= HexComparer.new([@cat_color]).brightness(0.77) %>;
|
||||
color: <%= @listing.social_preview_color(brightness: 0.77) %>;
|
||||
}
|
||||
|
||||
.preview-category {
|
||||
|
|
@ -78,7 +78,7 @@
|
|||
<%= sanitize_rendered_markdown(@listing.processed_html) %>
|
||||
</div>
|
||||
<div class="preview-category">
|
||||
<%= @category %>
|
||||
<%= @listing.social_preview_category %>
|
||||
</div>
|
||||
<div class="preview-dev-logo">
|
||||
<%= inline_svg_tag("devlistings-horizontal.svg", class: "logo", size: "30vw*10vw", aria: false, title: "DEV logo") %>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
class AddSocialPreviewColumnsToClassifiedListingCategories < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :classified_listing_categories, :social_preview_description, :string
|
||||
add_column :classified_listing_categories, :social_preview_color, :string
|
||||
end
|
||||
end
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 2020_05_01_032629) do
|
||||
ActiveRecord::Schema.define(version: 2020_05_04_075409) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
|
@ -316,6 +316,8 @@ ActiveRecord::Schema.define(version: 2020_05_01_032629) do
|
|||
t.string "name", null: false
|
||||
t.string "rules", null: false
|
||||
t.string "slug", null: false
|
||||
t.string "social_preview_color"
|
||||
t.string "social_preview_description"
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["name"], name: "index_classified_listing_categories_on_name", unique: true
|
||||
t.index ["slug"], name: "index_classified_listing_categories_on_slug", unique: true
|
||||
|
|
|
|||
|
|
@ -1,12 +1,24 @@
|
|||
namespace :temporary do
|
||||
namespace :classified_listings do
|
||||
desc "Backfill classified listings categories"
|
||||
task backfill_categories: :environment do
|
||||
ClassifiedListing::CATEGORIES_AVAILABLE.each do |key, attributes|
|
||||
category = ClassifiedListingCategory.find_or_create_by!(attributes.merge(slug: key))
|
||||
ClassifiedListing.
|
||||
where(category: key.to_s).
|
||||
update_all(classified_listing_category_id: category.id)
|
||||
desc "Backfill social preview info for classified listings categories"
|
||||
task backfill_social_preview_info: :environment do
|
||||
info = {
|
||||
"collabs": ["Collaborators Wanted", "#5ae8d9"],
|
||||
"cfp": ["Call For Proposal", "#f58f8d"],
|
||||
"forhire": ["Available For Hire", "#b78cf4"],
|
||||
"education": ["Education", "#5aabe8"],
|
||||
"jobs": ["Now Hiring", "#53c3ad"],
|
||||
"mentors": ["Offering Mentorship", "#a69ee8"],
|
||||
"mentees": ["Looking For Mentorship", "#88aedb"],
|
||||
"forsale": ["Stuff For Sale", "#d0adfb"],
|
||||
"events": ["Upcoming Event", "#f8b3d0"],
|
||||
"misc": ["Miscellaneous", "#6393ff"],
|
||||
"products": ["Products & Tools", "#5ae8d9"]
|
||||
}
|
||||
info.each do |slug, (description, color)|
|
||||
ClassifiedListingCategory.
|
||||
where(slug:slug).
|
||||
update(social_preview_description: description, social_preview_color: color)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
42
spec/decorators/classified_listing_decorator_spec.rb
Normal file
42
spec/decorators/classified_listing_decorator_spec.rb
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe ClassifiedListingDecorator, type: :decorator do
|
||||
let_it_be_readonly(:category) { create(:classified_listing_category) }
|
||||
let(:decorated_listing) do
|
||||
build(:classified_listing, classified_listing_category: category).decorate
|
||||
end
|
||||
|
||||
describe "#social_preview_category" do
|
||||
it "returns the category name if the social preview category is blank" do
|
||||
allow(category).to receive(:social_preview_description).and_return(nil)
|
||||
|
||||
expect(decorated_listing.social_preview_category).to eq(category.name)
|
||||
end
|
||||
|
||||
it "returns the category's social preview descripton if available" do
|
||||
expect(decorated_listing.social_preview_category).
|
||||
to eq(category.social_preview_description)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#social_preview_color" do
|
||||
it "returns the default color if social preview color is blank" do
|
||||
allow(category).to receive(:social_preview_color).and_return(nil)
|
||||
|
||||
expect(decorated_listing.social_preview_color).
|
||||
to eq(ClassifiedListingDecorator::DEFAULT_COLOR)
|
||||
end
|
||||
|
||||
it "returns the category's social preview color if available" do
|
||||
expect(decorated_listing.social_preview_color).
|
||||
to eq(category.social_preview_color)
|
||||
end
|
||||
|
||||
it "can modify the brightness" do
|
||||
color = category.social_preview_color
|
||||
|
||||
expect(decorated_listing.social_preview_color(brightness: 0.8)).
|
||||
to eq(HexComparer.new([color]).brightness(0.8))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -4,17 +4,23 @@ FactoryBot.define do
|
|||
cost { [1, 5, 25].sample }
|
||||
rules { Faker::Hipster.paragraph(sentence_count: 1) }
|
||||
slug { "education" }
|
||||
social_preview_description { "Education" }
|
||||
social_preview_color { "#5aabe8" }
|
||||
|
||||
trait :cfp do
|
||||
name { "Conference CFP" }
|
||||
slug { "cfp" }
|
||||
cost { 5 }
|
||||
social_preview_description { "Call For Proposal" }
|
||||
social_preview_color { "#f58f8d" }
|
||||
end
|
||||
|
||||
trait :jobs do
|
||||
name { "Job Listings" }
|
||||
slug { "jobs" }
|
||||
cost { 1 }
|
||||
social_preview_description { "Now Hiring" }
|
||||
social_preview_color { "#53c3ad" }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -12,5 +12,30 @@ RSpec.describe ClassifiedListingCategory, type: :model do
|
|||
it { is_expected.to validate_presence_of(:slug) }
|
||||
it { is_expected.to validate_uniqueness_of(:name) }
|
||||
it { is_expected.to validate_uniqueness_of(:slug) }
|
||||
|
||||
context "when validating social preview colors" do
|
||||
let(:category) { build(:classified_listing_category) }
|
||||
|
||||
it "rejects invalid formats" do
|
||||
category.social_preview_color = "#DEV.TO"
|
||||
category.validate
|
||||
|
||||
expect(category.errors[:social_preview_color]).to eq(["is invalid"])
|
||||
end
|
||||
|
||||
it "normalizes the input to lowercase before validation" do
|
||||
category.social_preview_color = "#CCCCCC"
|
||||
category.validate
|
||||
|
||||
expect(category.social_preview_color).to eq("#cccccc")
|
||||
end
|
||||
|
||||
it "accepts missing social preview colors" do
|
||||
category.social_preview_color = nil
|
||||
category.validate
|
||||
|
||||
expect(category).to be_valid
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue