Skip to content

Commit

Permalink
Merge pull request #847 from distributive/identity-selection-improvem…
Browse files Browse the repository at this point in the history
…ents

Identity selection improvements
  • Loading branch information
plural authored Sep 29, 2024
2 parents 9cd6fed + 8a20877 commit ec08016
Show file tree
Hide file tree
Showing 5 changed files with 186 additions and 80 deletions.
57 changes: 36 additions & 21 deletions app/Resources/views/Builder/initbuild.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{% block head %}
<style>
/* Hide unmatched identities */
.hidden-format, .hidden-misc {
.hidden-side, .hidden-faction, .hidden-format, .hidden-misc {
display: none;
}
/* Overwrite Bootstrap to prevent hidden identities messing up borders */
Expand All @@ -19,6 +19,10 @@
justify-content: flex-start;
align-items: center;
}
/* Identify selected options */
.active-setting {
text-decoration: underline;
}
</style>
<script src="{{ asset('/js/initbuild.js') }}"></script>
{% endblock %}
Expand All @@ -32,7 +36,11 @@
<div class="col-sm-8">
<div class="panel panel-default">
<!-- Default panel contents -->
<div class="panel-heading"><b>Choose your identity</b></div>
<div class="panel-heading" style="display: flex; justify-content: space-between;">
<b>Choose your identity</b>
{% set altSide = side == 'Corp' ? 'runner' : 'corp' %}
<a href="#" id="switch-side" value="{{ altSide }}">Switch to {{ altSide }} deck</a>
</div>
<!-- ID filter -->
<div class="panel-heading">
<div style="display: flex; flex-wrap: wrap;">
Expand All @@ -46,34 +54,41 @@
<a href="#" class="option-format" value="all">All</a>
</div>
</div>
<div style="flex-grow: 1;">
<select class="form-control" name="faction-filter" id="faction-filter">
<option value="all">All factions</option>
{% for faction in factions %}
<option value="{{ faction.code }}">
{{ faction.name }}
</option>
<div style="flex-grow: 1;" id="faction-options">
<div id="corp-faction-options" {% if side == "Runner" %}style="display: none;"{% endif %} >Faction |
{% for faction in (corp_factions) %}
<a href="#" class="option-faction" value="{{ faction.code }}">{{ faction.name }}</a> |
{% endfor %}
</select>
<a href="#" class="option-faction" value="neutral-corp">Neutral</a> |
<a href="#" class="option-faction" value="all">All</a>
</div>
<div id="runner-faction-options" {% if side == "Corp" %}style="display: none;"{% endif %}>Faction |
{% for faction in (runner_factions) %}
<a href="#" class="option-faction" value="{{ faction.code }}">{{ faction.name }}</a> |
{% endfor %}
<a href="#" class="option-faction" value="mini">Mini faction</a> |
<a href="#" class="option-faction" value="neutral-runner">Neutral</a> |
<a href="#" class="option-faction" value="all">All</a>
</div>
</div>
</div>
</div>
<div class="panel-heading" id="panel-title-filter">
<input type="text" class="form-control input-sm" id="title-filter" placeholder="Filter by name" tabindex="1">
</div>
<!-- List group -->
<!-- List groups -->
<div class="list-group">
{% for identity in identities %}
{% set banned = identity.code in banned_cards|keys %}
{% set rotated = identity.pack.cycle.rotated %}
<a href="{{ path('deck_initbuild', {card_code:identity.code}) }}"
class="identity list-group-item faction-{{ identity.faction.code }} pack-{{ identity.pack.code }} {% if rotated %}rotated{% endif %} {% if banned %}banned{% endif %}"
data-code="{{ identity.code }}">
<svg class="typeIcon" aria-label="{{ identity.faction.name }}" data-icon-color="{{ identity.faction.code }}" style="transform:translateY(2px);margin-right:0.5em;"><use xlink:href="/images/icons.svg#faction-{{ identity.faction.code }}"></use></svg>
<span class="name">{{ identity.title(app.request.locale) }}</span>
<span class="small">({{ identity.pack.name }})</span>
<span style="margin-left: 4px;" class="legality-indicator {% if rotated %}legality-rotated{% endif %} {% if banned %}legality-banned{% endif %}"></span>
</a>
{% set banned = identity.code in banned_cards|keys %}
{% set rotated = identity.pack.cycle.rotated %}
<a href="{{ path('deck_initbuild', {card_code:identity.code}) }}"
class="identity list-group-item side-{{ identity.side.code }} faction-{{ identity.faction.code }} pack-{{ identity.pack.code }} {% if rotated %}rotated{% endif %} {% if banned %}banned{% endif %} {% if identity.faction.isMini %}mini-faction{% endif %}"
data-code="{{ identity.code }}">
<svg class="typeIcon" aria-label="{{ identity.faction.name }}" data-icon-color="{{ identity.faction.code }}" style="transform:translateY(2px);margin-right:0.5em;"><use xlink:href="/images/icons.svg#faction-{{ identity.faction.code }}"></use></svg>
<span class="name">{{ identity.title(app.request.locale) }}</span>
<span class="small">({{ identity.pack.name }})</span>
<span style="margin-left: 4px;" class="legality-indicator {% if rotated %}legality-rotated{% endif %} {% if banned %}legality-banned{% endif %}"></span>
</a>
{% endfor %}
</div>
</div>
Expand Down
30 changes: 24 additions & 6 deletions src/AppBundle/Controller/BuilderController.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,36 @@ public function buildformAction(string $side_text, EntityManagerInterface $entit
]);

$identities = $entityManager->getRepository('AppBundle:Card')->findBy([
"side" => $side,
"type" => $type,
], [
"faction" => "ASC",
"title" => "ASC",
]);
$identities = $cardsData->select_only_latest_cards($identities);
// Sorting minifactions and neutrals like this because whatever PHP version this is can't do stable sorting
// Resulting array is [ normal factions ... mini factions ... neutral ]
$identities = array_merge(
array_filter($identities, function($identity) {
return !$identity->getFaction()->getIsNeutral() && !$identity->getFaction()->getIsMini();
}),
array_filter($identities, function($identity) {
return $identity->getFaction()->getIsMini();
}),
array_filter($identities, function($identity) {
return $identity->getFaction()->getIsNeutral();
}),
);

$factions = $entityManager->getRepository('AppBundle:Faction')->findBy([
"side" => $side,
], [
$factions = $entityManager->getRepository('AppBundle:Faction')->findBy([], [
"name" => "ASC",
]);
$corp_factions = array_filter($factions, function($faction) {
return $faction->getSide()->getCode() == "corp" && !$faction->getIsNeutral();
});
$runner_factions = array_filter($factions, function($faction) {
return $faction->getSide()->getCode() == "runner" && !$faction->getIsNeutral() && !$faction->getIsMini();
});

$identities = $cardsData->select_only_latest_cards($identities);
$banned_cards = array();
foreach ($identities as $id) {
$i = $cardsData->get_mwl_info([$id], true /* active_only */);
Expand All @@ -75,7 +91,9 @@ public function buildformAction(string $side_text, EntityManagerInterface $entit
'pagedescription' => "Choose your identity to start building a custom deck.",
"identities" => $identities,
"banned_cards" => $banned_cards,
"factions" => $factions
"corp_factions" => $corp_factions,
"runner_factions" => $runner_factions,
"side" => $side,
],

$response
Expand Down
9 changes: 9 additions & 0 deletions src/AppBundle/Entity/Faction.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ public function normalize()
'code' => $this->code,
'color' => $this->color,
'is_mini' => $this->isMini,
'is_neutral' => $this->getIsNeutral(),
'name' => $this->name,
'side_code' => $this->side ? $this->side->getCode() : null
];
Expand Down Expand Up @@ -153,6 +154,14 @@ public function setIsMini(bool $isMini)
return $this;
}

/**
* @return bool
*/
public function getIsNeutral()
{
return str_contains($this->code, 'neutral');
}

/**
* @return Side
*/
Expand Down
4 changes: 0 additions & 4 deletions web/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -2062,10 +2062,6 @@ code {
color: var(--nrdb-color--btn);
}

#deck-builder #faction-filter.form-control {
background-color: var(--nrdb-color--card) !important;
}

.table-hover > tbody > tr:hover {
background-color: var(--nrdb-color--border);
}
Expand Down
166 changes: 117 additions & 49 deletions web/js/initbuild.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ $(function() {
// Check if the preview is showing a card that is currently visible
function checkPreview() {
let id = $(`.identity[data-code="${$('#cardimg').attr('data-code')}"]`);
if (id.hasClass('hidden-format') || id.hasClass('hidden-misc')) {
if (id.hasClass('hidden-side') || id.hasClass('hidden-faction') || id.hasClass('hidden-format') || id.hasClass('hidden-misc')) {
$('#cardimg').hide();
}
}
Expand All @@ -30,77 +30,143 @@ $(function() {
}
});

// Update the ID list when the format is changed
function updateFormat(format) {
// Sets the faction selection to the appropriate side and refreshes the list of cards
function updateSide(side) {
// Update menu
if (side === 'corp') {
$('#corp-faction-options').show();
$('#runner-faction-options').hide();
$('#switch-side').attr('value', 'runner');
$('#switch-side').text($('#switch-side').text().replace("corp", "runner"));
} else {
$('#corp-faction-options').hide();
$('#runner-faction-options').show();
$('#switch-side').attr('value', 'corp');
$('#switch-side').text($('#switch-side').text().replace("runner", "corp"));
}
// Filter cards
$('.identity').each(function(id, i) {
if ($(this).hasClass('side-' + side)) {
$(this).removeClass('hidden-side');
} else {
$(this).addClass('hidden-side');
}
});
// Reset faction
updateFaction('all');
}

// Update the ID list when the faction is changed
function updateFaction(faction) {
// Update settings
$(`.option-faction[value!="${faction}"]`).removeClass('active-setting');
$(`.option-faction[value="${faction}"]`).addClass('active-setting');
// Filter cards
if (faction === 'all') {
$('.identity').each(function(id, i) {
// All (only show legality indicators on all)
if (format === 'all') {
$(this).removeClass('hidden-format');
$(this).find('.legality-indicator').show ();
return;
$(this).removeClass('hidden-faction');
});
} else if (faction === 'mini') {
$('.identity').each(function(id, i) {
if ($(this).hasClass('mini-faction')) {
$(this).removeClass('hidden-faction');
} else {
$(this).addClass('hidden-faction');
}
});
} else {
$('.identity').each(function(id, i) {
if ($(this).hasClass('faction-' + faction)) {
$(this).removeClass('hidden-faction');
} else {
$(this).find('.legality-indicator').hide ();
}
// Other formats
let visible = true;
// Startup
if (format === 'startup') {
visible = ['sg', 'su21', 'tai', 'rwr'].some(p => $(this).hasClass('pack-' + p)); // Hardcoded Startup Codes
}
// Standard
else if (format === 'standard') {
visible = !($(this).hasClass('banned') || $(this).hasClass('rotated'));
}
// Eternal
else if (format === 'eternal') {
visible = true
}
// Draft
if ($(this).hasClass('pack-draft')) {
visible = format === 'draft';
}
else if (format === 'draft') {
visible = false
}
// Other (neutral Gateway IDs and the multiplayer NAPD ID)
if (['24001', '30076', '30077'].includes($(this).attr('data-code'))) {
visible = format === 'other';
}
else if (format === 'other') {
visible = false
$(this).addClass('hidden-faction');
}
// Apply effect
if (visible)
$(this).removeClass('hidden-format');
else
$(this).addClass('hidden-format');
});
}
}

// Update the ID list when the format is changed
function updateFormat(format) {
// Update settings
$(`.option-format[value!="${format}"]`).removeClass('active-setting');
$(`.option-format[value="${format}"]`).addClass('active-setting');
// Filter cards
$('.identity').each(function(id, i) {
// All (only show legality indicators on all)
if (format === 'all') {
$(this).removeClass('hidden-format');
$(this).find('.legality-indicator').show ();
return;
} else {
$(this).find('.legality-indicator').hide ();
}
// Other formats
let visible = true;
// Startup
if (format === 'startup') {
visible = ['sg', 'su21', 'tai', 'rwr'].some(p => $(this).hasClass('pack-' + p)); // Hardcoded Startup Codes
}
// Standard
else if (format === 'standard') {
visible = !($(this).hasClass('banned') || $(this).hasClass('rotated'));
}
// Eternal
else if (format === 'eternal') {
visible = true
}
// Draft
if ($(this).hasClass('pack-draft')) {
visible = format === 'draft';
}
else if (format === 'draft') {
visible = false
}
// Other (neutral Gateway IDs and the multiplayer NAPD ID)
if (['24001', '30076', '30077'].includes($(this).attr('data-code'))) {
visible = format === 'other';
}
else if (format === 'other') {
visible = false
}
// Apply effect
if (visible)
$(this).removeClass('hidden-format');
else
$(this).addClass('hidden-format');
});
}

// Update the ID list when any other parameter is changed
function updateMisc() {
let faction = $('#faction-filter').val();
let search = $('#title-filter').val().toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
$('.identity').each(function(id, i) {
if (faction !== 'all' && !$(this).hasClass('faction-' + faction) || !$(this).find('.name').html().toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").includes(search)) {
if (search && !$(this).find('.name').html().toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").includes(search)) {
$(this).addClass('hidden-misc');
return;
}
$(this).removeClass('hidden-misc');
});
}

// Filter on format selected
$('.option-format').on('click', function(event) {
updateFormat($(this).attr('value'));
// Changing side
$('#switch-side').on('click', function(event) {
updateSide($(this).attr('value'));
checkPreview();
event.preventDefault();
});

// Filter on faction selected
$('#faction-filter').change(function() {
updateMisc();
$('.option-faction').on('click', function(event) {
updateFaction($(this).attr('value'));
checkPreview();
event.preventDefault();
});

// Filter on format selected
$('.option-format').on('click', function(event) {
updateFormat($(this).attr('value'));
checkPreview();
event.preventDefault();
});

// Filter on search updated
Expand All @@ -110,5 +176,7 @@ $(function() {
});

// Filter on page refresh
updateSide($('#switch-side').attr('value') == 'runner' ? 'corp' : 'runner');
updateFormat('standard');
updateMisc();
});

0 comments on commit ec08016

Please sign in to comment.