improve achievement management and and views
This commit is contained in:
32
app/controllers/achievements_controller.rb
Normal file
32
app/controllers/achievements_controller.rb
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AchievementsController < ProtectedController
|
||||||
|
def index
|
||||||
|
@wow_achievement_categories = WowAchievementCategory.base_categories.order(display_order: :asc)
|
||||||
|
@wow_achievements = nil
|
||||||
|
@wow_last_completed_achievements = CompletedWowAchievement.where(
|
||||||
|
wow_character: current_user.wow_characters
|
||||||
|
).includes(:wow_character, wow_achievement: :wow_achievement_criterium).order(completed_timestamp: :desc).first(5)
|
||||||
|
@wow_achievement_category = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
@wow_achievement_category = WowAchievementCategory.find(params[:id])
|
||||||
|
@wow_achievement_categories = @wow_achievement_category.child_categories.order(display_order: :asc)
|
||||||
|
@wow_achievements = @wow_achievement_category.wow_achievements.includes(
|
||||||
|
wow_achievement_criterium: :child_criteria
|
||||||
|
).order(display_order: :asc)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# TODO
|
||||||
|
# Find a way to get the last achievement accomplished that were not already achievement by another character
|
||||||
|
# This will return all WowAchievement only completed by one character of the current user
|
||||||
|
# achievements = WowAchievement.joins(:completed_wow_achievements).where('completed_wow_achievements.wow_character_id': current_user.wow_characters).group(:id).having("count(completed_wow_achievements.id) < 2")
|
||||||
|
#
|
||||||
|
# This will return all the CompletedWowAchievement of the previous list
|
||||||
|
# completed_achievements = CompletedWowAchievement.where(wow_character: current_user.wow_characters, wow_achievement: achievements)
|
||||||
|
#
|
||||||
|
# The problem is that these completed_achivements all have a completed_timestamp at Thu, 01 Jan 1970 00:00:00.000000000 UTC +00:00
|
||||||
|
#
|
||||||
|
# It's probably required to use the WowAchievementCriterium to sort that
|
||||||
7
app/helpers/achievements_helper.rb
Normal file
7
app/helpers/achievements_helper.rb
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module AchievementsHelper
|
||||||
|
def achievement_completed(achievement_id, user)
|
||||||
|
CompletedWowAchievement.where(wow_achievement_id: achievement_id, wow_character: user.wow_characters).exists?
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -19,4 +19,6 @@ class WowAchievement < ApplicationRecord
|
|||||||
|
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
validates :achievement_id, presence: true, uniqueness: true
|
validates :achievement_id, presence: true, uniqueness: true
|
||||||
|
|
||||||
|
scope :base_achievements, -> { where(prerequisite_achievement: nil) }
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -4,8 +4,16 @@ class WowAchievementCategory < ApplicationRecord
|
|||||||
extend Mobility
|
extend Mobility
|
||||||
translates :name
|
translates :name
|
||||||
|
|
||||||
|
belongs_to :parent_category, class_name: 'WowAchievementCategory', optional: true
|
||||||
|
has_many :child_categories,
|
||||||
|
class_name: 'WowAchievementCategory',
|
||||||
|
foreign_key: 'parent_category_id',
|
||||||
|
dependent: :nullify,
|
||||||
|
inverse_of: :parent_category
|
||||||
has_many :wow_achievements, dependent: :destroy
|
has_many :wow_achievements, dependent: :destroy
|
||||||
|
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
validates :category_id, presence: true, uniqueness: true
|
validates :category_id, presence: true, uniqueness: true
|
||||||
|
|
||||||
|
scope :base_categories, -> { where(parent_category: nil) }
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ class WowAchievementCriterium < ApplicationRecord
|
|||||||
dependent: :destroy,
|
dependent: :destroy,
|
||||||
inverse_of: :parent_criterium
|
inverse_of: :parent_criterium
|
||||||
belongs_to :parent_criterium, class_name: 'WowAchievementCriterium', optional: true
|
belongs_to :parent_criterium, class_name: 'WowAchievementCriterium', optional: true
|
||||||
|
|
||||||
has_many :completed_wow_achievement_criteria, dependent: :destroy
|
has_many :completed_wow_achievement_criteria, dependent: :destroy
|
||||||
has_many :wow_characters, through: :completed_wow_achievement_criteria
|
has_many :wow_characters, through: :completed_wow_achievement_criteria
|
||||||
|
|
||||||
|
|||||||
76
app/views/achievements/_achievements.html.erb
Normal file
76
app/views/achievements/_achievements.html.erb
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
<div class="row">
|
||||||
|
<div class="col-3">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<% if wow_achievement_category %><h3> Achievement category: <%= wow_achievement_category.name %></h3><% end %>
|
||||||
|
<div class="d-grid gap-2">
|
||||||
|
<% wow_achievement_categories.each do |category| %>
|
||||||
|
<%= link_to category.name, "/#{locale}/achievements/#{category.id}", class: "btn btn-outline-dark" %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<% if wow_achievement_category&.parent_category %>
|
||||||
|
<%= link_to "Back", "/#{locale}/achievements/#{wow_achievement_category.parent_category.id}", class: "btn btn-outline-dark" %>
|
||||||
|
<% elsif wow_achievement_category %>
|
||||||
|
<%= link_to "Back", "/#{locale}/achievements", class: "btn btn-outline-dark" %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% if wow_achievements %>
|
||||||
|
<div class="col-6">
|
||||||
|
<h3> Achievement:</h3>
|
||||||
|
<div class="d-grid gap-2">
|
||||||
|
<% wow_achievements.each do |achievement| %>
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header <% if achievement_completed(achievement.id, current_user) %>bg-success text-white<% else %>bg-secondary text-white<% end %>">
|
||||||
|
<%= achievement.name %><% if Rails.env.development? %> - ID: <%= achievement.achievement_id %><% end %>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<p class="card-text">Description: <%= achievement.description %></p>
|
||||||
|
<p class="card-text">Criterium: <%= achievement&.wow_achievement_criterium&.description %></p>
|
||||||
|
<div class="row">
|
||||||
|
<% achievement&.wow_achievement_criterium&.child_criteria&.each do |criterium| %>
|
||||||
|
<div class="col-3">
|
||||||
|
<p class="card-text"><%= criterium&.description %></p>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% elsif wow_last_completed_achievements %>
|
||||||
|
<div class="col-6">
|
||||||
|
<h3> Last achievement:</h3>
|
||||||
|
<div class="d-grid gap-2">
|
||||||
|
<% wow_last_completed_achievements.each do |achievement| %>
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<%= achievement.wow_achievement.name %> - ID: <%= achievement.wow_achievement.achievement_id %>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<p class="card-text">Description: <%= achievement.wow_achievement.description %></p>
|
||||||
|
<p class="card-text">Criterium: <%= achievement&.wow_achievement.wow_achievement_criterium&.description %></p>
|
||||||
|
<% if achievement&.wow_achievement.wow_achievement_criterium.child_criteria %>
|
||||||
|
<div class="row">
|
||||||
|
<% achievement&.wow_achievement.wow_achievement_criterium.child_criteria.each do |criterium| %>
|
||||||
|
<div class="col-3">
|
||||||
|
<p class="card-text"><%= criterium&.description %></p>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<p class="card-text">Completed by: <%= link_to achievement.wow_character.name, achievement.wow_character, data: { turbo: false } %></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
5
app/views/achievements/index.html.erb
Normal file
5
app/views/achievements/index.html.erb
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<h2>Achievement list</h2>
|
||||||
|
|
||||||
|
<%= turbo_frame_tag 'achievements' do %>
|
||||||
|
<%= render partial: 'achievements/achievements', locals: { wow_achievement_category: @wow_achievement_category, wow_achievement_categories: @wow_achievement_categories, wow_achievements: @wow_achievements, wow_last_completed_achievements: @wow_last_completed_achievements } %>
|
||||||
|
<% end %>
|
||||||
5
app/views/achievements/show.html.erb
Normal file
5
app/views/achievements/show.html.erb
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<h2>Achievement list</h2>
|
||||||
|
|
||||||
|
<%= turbo_frame_tag 'achievements' do %>
|
||||||
|
<%= render partial: 'achievements/achievements', locals: { wow_achievement_category: @wow_achievement_category, wow_achievement_categories: @wow_achievement_categories, wow_achievements: @wow_achievements, wow_last_completed_achievements: nil } %>
|
||||||
|
<% end %>
|
||||||
@@ -19,6 +19,9 @@
|
|||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link <%= 'active' if current_page?(rp_worlds_path) %>" aria-current="page" href="<%= rp_worlds_path %>"><%= t('layouts.navbar.worlds') %></a>
|
<a class="nav-link <%= 'active' if current_page?(rp_worlds_path) %>" aria-current="page" href="<%= rp_worlds_path %>"><%= t('layouts.navbar.worlds') %></a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link <%= 'active' if current_page?(achievements_path) %>" aria-current="page" href="<%= achievements_path %>"><%= t('layouts.navbar.achievements') %></a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
|
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
|
||||||
<%= render 'layouts/locales' %>
|
<%= render 'layouts/locales' %>
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ class WowAchievementCategoriesWorker < WowSidekiqWorker
|
|||||||
end
|
end
|
||||||
|
|
||||||
wow_category.save
|
wow_category.save
|
||||||
|
|
||||||
|
WowAchievementCategoryDetailWorker.perform_async(wow_category.category_id) if wow_category.persisted?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
21
app/workers/wow_achievement_category_detail_worker.rb
Normal file
21
app/workers/wow_achievement_category_detail_worker.rb
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class WowAchievementCategoryDetailWorker < WowSidekiqWorker
|
||||||
|
def perform(category_id)
|
||||||
|
return unless (wow_achievement_category = WowAchievementCategory.find_by(category_id: category_id))
|
||||||
|
|
||||||
|
RBattlenet.set_options(locale: 'en_GB')
|
||||||
|
result = RBattlenet::Wow::AchievementCategory.find(category_id)
|
||||||
|
|
||||||
|
return unless result.status_code == 200
|
||||||
|
|
||||||
|
wow_achievement_category.is_guild_category = result.is_guild_category
|
||||||
|
wow_achievement_category.display_order = result.display_order
|
||||||
|
|
||||||
|
if result.parent_category
|
||||||
|
wow_achievement_category.parent_category = WowAchievementCategory.find_by(category_id: result.parent_category.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
wow_achievement_category.save
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -25,7 +25,11 @@ class WowAchievementDetailWorker < WowSidekiqWorker
|
|||||||
wow_achievement.prerequisite_achievement = WowAchievement.find_by(achievement_id: result.prerequisite_achievement.id) if result.prerequisite_achievement
|
wow_achievement.prerequisite_achievement = WowAchievement.find_by(achievement_id: result.prerequisite_achievement.id) if result.prerequisite_achievement
|
||||||
wow_achievement.wow_achievement_category = WowAchievementCategory.find_by(category_id: result.category.id) if result.category
|
wow_achievement.wow_achievement_category = WowAchievementCategory.find_by(category_id: result.category.id) if result.category
|
||||||
wow_achievement.wow_achievement_criterium = find_or_create_wow_achievement_criterium(result.criteria) if result.criteria
|
wow_achievement.wow_achievement_criterium = find_or_create_wow_achievement_criterium(result.criteria) if result.criteria
|
||||||
wow_achievement.icon = RBattlenet::Wow::AchievementMedia.find(result.media.id).assets[0].value if result.media
|
|
||||||
|
if result.media
|
||||||
|
icon = RBattlenet::Wow::AchievementMedia.find(result.media.id)
|
||||||
|
wow_achievement.icon = icon.assets.first.value if icon.assets.first
|
||||||
|
end
|
||||||
|
|
||||||
wow_achievement.save
|
wow_achievement.save
|
||||||
end
|
end
|
||||||
@@ -34,9 +38,11 @@ class WowAchievementDetailWorker < WowSidekiqWorker
|
|||||||
wow_achievement_criterium = WowAchievementCriterium.find_or_initialize_by(criterium_id: criteria.id)
|
wow_achievement_criterium = WowAchievementCriterium.find_or_initialize_by(criterium_id: criteria.id)
|
||||||
|
|
||||||
wow_achievement_criterium.amount = criteria.amount
|
wow_achievement_criterium.amount = criteria.amount
|
||||||
|
if criteria.description
|
||||||
locales.each do |locale|
|
locales.each do |locale|
|
||||||
Mobility.with_locale(locale[0]) { wow_achievement_criterium.description = criteria.description[locale[1]] }
|
Mobility.with_locale(locale[0]) { wow_achievement_criterium.description = criteria.description[locale[1]] }
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if criteria.operator
|
if criteria.operator
|
||||||
wow_achievement_criterium.operator_type = criteria.operator.type
|
wow_achievement_criterium.operator_type = criteria.operator.type
|
||||||
@@ -51,9 +57,13 @@ class WowAchievementDetailWorker < WowSidekiqWorker
|
|||||||
wow_child_achievement_criterium = WowAchievementCriterium.find_or_initialize_by(criterium_id: child_criterium.id)
|
wow_child_achievement_criterium = WowAchievementCriterium.find_or_initialize_by(criterium_id: child_criterium.id)
|
||||||
wow_child_achievement_criterium.parent_criterium = wow_achievement_criterium
|
wow_child_achievement_criterium.parent_criterium = wow_achievement_criterium
|
||||||
wow_child_achievement_criterium.amount = child_criterium.amount
|
wow_child_achievement_criterium.amount = child_criterium.amount
|
||||||
|
|
||||||
|
if child_criterium.description
|
||||||
locales.each do |locale|
|
locales.each do |locale|
|
||||||
Mobility.with_locale(locale[0]) { wow_child_achievement_criterium.description = child_criterium.description[locale[1]] }
|
Mobility.with_locale(locale[0]) { wow_child_achievement_criterium.description = child_criterium.description[locale[1]] }
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
wow_child_achievement_criterium.save
|
wow_child_achievement_criterium.save
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class WowCharactersWorker < WowSidekiqWorker
|
|||||||
WowCharacterDetailWorker.perform_async(wow_char.character_id)
|
WowCharacterDetailWorker.perform_async(wow_char.character_id)
|
||||||
WowCharacterPositionsWorker.perform_async(wow_char.character_id)
|
WowCharacterPositionsWorker.perform_async(wow_char.character_id)
|
||||||
WowStandingWorker.perform_async(wow_char.character_id)
|
WowStandingWorker.perform_async(wow_char.character_id)
|
||||||
WowCharacterAchievementsWorker.perform_async(wow_char.character_id)
|
# WowCharacterAchievementsWorker.perform_async(wow_char.character_id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ Rails.application.routes.draw do
|
|||||||
resources :wow_mounts, only: [:index, :show]
|
resources :wow_mounts, only: [:index, :show]
|
||||||
resources :wow_pets, only: [:index, :show]
|
resources :wow_pets, only: [:index, :show]
|
||||||
resources :wow_reputations, only: [:index, :show]
|
resources :wow_reputations, only: [:index, :show]
|
||||||
|
resources :achievements, only: [:index, :show]
|
||||||
resources :rp_worlds
|
resources :rp_worlds
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
class AddWowAchievementCategorySelfJoin < ActiveRecord::Migration[6.1]
|
||||||
|
def change
|
||||||
|
add_reference :wow_achievement_categories, :parent_category, foreign_key: { to_table: :wow_achievement_categories }
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
class AddColumnsToWowAchievementCategory < ActiveRecord::Migration[6.1]
|
||||||
|
def change
|
||||||
|
add_column :wow_achievement_categories, :is_guild_category, :boolean
|
||||||
|
add_column :wow_achievement_categories, :display_order, :integer
|
||||||
|
end
|
||||||
|
end
|
||||||
7
db/schema.rb
generated
7
db/schema.rb
generated
@@ -10,7 +10,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: 2021_08_15_130405) do
|
ActiveRecord::Schema.define(version: 2021_08_15_182820) 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"
|
||||||
@@ -118,7 +118,11 @@ ActiveRecord::Schema.define(version: 2021_08_15_130405) do
|
|||||||
t.jsonb "name"
|
t.jsonb "name"
|
||||||
t.datetime "created_at", precision: 6, null: false
|
t.datetime "created_at", precision: 6, null: false
|
||||||
t.datetime "updated_at", precision: 6, null: false
|
t.datetime "updated_at", precision: 6, null: false
|
||||||
|
t.bigint "parent_category_id"
|
||||||
|
t.boolean "is_guild_category"
|
||||||
|
t.integer "display_order"
|
||||||
t.index ["category_id"], name: "index_wow_achievement_categories_on_category_id", unique: true
|
t.index ["category_id"], name: "index_wow_achievement_categories_on_category_id", unique: true
|
||||||
|
t.index ["parent_category_id"], name: "index_wow_achievement_categories_on_parent_category_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "wow_achievement_criteria", force: :cascade do |t|
|
create_table "wow_achievement_criteria", force: :cascade do |t|
|
||||||
@@ -531,6 +535,7 @@ ActiveRecord::Schema.define(version: 2021_08_15_130405) do
|
|||||||
t.index ["wow_reputation_id"], name: "index_wow_standings_on_wow_reputation_id"
|
t.index ["wow_reputation_id"], name: "index_wow_standings_on_wow_reputation_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
add_foreign_key "wow_achievement_categories", "wow_achievement_categories", column: "parent_category_id"
|
||||||
add_foreign_key "wow_achievement_criteria", "wow_achievement_criteria", column: "parent_criterium_id"
|
add_foreign_key "wow_achievement_criteria", "wow_achievement_criteria", column: "parent_criterium_id"
|
||||||
add_foreign_key "wow_achievements", "wow_achievements", column: "prerequisite_achievement_id"
|
add_foreign_key "wow_achievements", "wow_achievements", column: "prerequisite_achievement_id"
|
||||||
add_foreign_key "wow_characters", "wow_geo_positions", column: "bind_position_id"
|
add_foreign_key "wow_characters", "wow_geo_positions", column: "bind_position_id"
|
||||||
|
|||||||
Reference in New Issue
Block a user