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 :achievement_id, presence: true, uniqueness: true
|
||||
|
||||
scope :base_achievements, -> { where(prerequisite_achievement: nil) }
|
||||
end
|
||||
|
||||
@@ -4,8 +4,16 @@ class WowAchievementCategory < ApplicationRecord
|
||||
extend Mobility
|
||||
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
|
||||
|
||||
validates :name, presence: true
|
||||
validates :category_id, presence: true, uniqueness: true
|
||||
|
||||
scope :base_categories, -> { where(parent_category: nil) }
|
||||
end
|
||||
|
||||
@@ -11,6 +11,7 @@ class WowAchievementCriterium < ApplicationRecord
|
||||
dependent: :destroy,
|
||||
inverse_of: :parent_criterium
|
||||
belongs_to :parent_criterium, class_name: 'WowAchievementCriterium', optional: true
|
||||
|
||||
has_many :completed_wow_achievement_criteria, dependent: :destroy
|
||||
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">
|
||||
<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 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 class="navbar-nav ms-auto mb-2 mb-lg-0">
|
||||
<%= render 'layouts/locales' %>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<div class="col-7">
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<%= render partial: 'wow_characters/reputations', locals: { standings: @wow_character.wow_standings.group_by { |standing| standing.wow_reputation.meta_wow_reputation_id }, meta_wow_reputations: @meta_wow_reputations } %>
|
||||
<%= render partial: 'wow_characters/reputations', locals: { standings: @wow_character.wow_standings.group_by { |standing| standing.wow_reputation.meta_wow_reputation_id}, meta_wow_reputations: @meta_wow_reputations } %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -17,6 +17,8 @@ class WowAchievementCategoriesWorker < WowSidekiqWorker
|
||||
end
|
||||
|
||||
wow_category.save
|
||||
|
||||
WowAchievementCategoryDetailWorker.perform_async(wow_category.category_id) if wow_category.persisted?
|
||||
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.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.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
|
||||
end
|
||||
@@ -34,8 +38,10 @@ class WowAchievementDetailWorker < WowSidekiqWorker
|
||||
wow_achievement_criterium = WowAchievementCriterium.find_or_initialize_by(criterium_id: criteria.id)
|
||||
|
||||
wow_achievement_criterium.amount = criteria.amount
|
||||
locales.each do |locale|
|
||||
Mobility.with_locale(locale[0]) { wow_achievement_criterium.description = criteria.description[locale[1]] }
|
||||
if criteria.description
|
||||
locales.each do |locale|
|
||||
Mobility.with_locale(locale[0]) { wow_achievement_criterium.description = criteria.description[locale[1]] }
|
||||
end
|
||||
end
|
||||
|
||||
if criteria.operator
|
||||
@@ -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.parent_criterium = wow_achievement_criterium
|
||||
wow_child_achievement_criterium.amount = child_criterium.amount
|
||||
locales.each do |locale|
|
||||
Mobility.with_locale(locale[0]) { wow_child_achievement_criterium.description = child_criterium.description[locale[1]] }
|
||||
|
||||
if child_criterium.description
|
||||
locales.each do |locale|
|
||||
Mobility.with_locale(locale[0]) { wow_child_achievement_criterium.description = child_criterium.description[locale[1]] }
|
||||
end
|
||||
end
|
||||
|
||||
wow_child_achievement_criterium.save
|
||||
end
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ class WowCharactersWorker < WowSidekiqWorker
|
||||
WowCharacterDetailWorker.perform_async(wow_char.character_id)
|
||||
WowCharacterPositionsWorker.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
|
||||
|
||||
Reference in New Issue
Block a user