From 48452e5de10e438805286d21a6ff21bc130ca9eb Mon Sep 17 00:00:00 2001 From: p0lygun Date: Tue, 20 Sep 2022 16:17:18 +0530 Subject: [PATCH 1/6] feat: added api to get/save tags from GT api --- bfportal/bfportal/static/js/bfportal.js | 13 ++++------ bfportal/core/helper.py | 26 +++++++++++++++++++ .../commands/ensure_initialization.py | 3 +++ bfportal/core/management/commands/portal.py | 18 +++---------- .../migrations/0051_delete_availabletags.py | 16 ++++++++++++ bfportal/core/models.py | 6 ----- bfportal/factory/management/commands/fake.py | 3 ++- .../factory/management/commands/playground.py | 3 ++- 8 files changed, 57 insertions(+), 31 deletions(-) create mode 100644 bfportal/core/helper.py create mode 100644 bfportal/core/migrations/0051_delete_availabletags.py diff --git a/bfportal/bfportal/static/js/bfportal.js b/bfportal/bfportal/static/js/bfportal.js index e354583..1bcf0a0 100644 --- a/bfportal/bfportal/static/js/bfportal.js +++ b/bfportal/bfportal/static/js/bfportal.js @@ -55,17 +55,14 @@ $(document).ready(function() { GTApiResponse.playgroundName = String; GTApiResponse.playgroundDescription = String; if (!GTApiResponse.hasOwnProperty('errors')) { - let tags = ""; - GTApiResponse.tag.forEach(elm => tags = tags.concat(elm.metadata.translations[0].localizedText, ",")); + GTApiResponse.tag.forEach(elm => { + + }); + + GTApiResponse = GTApiResponse.validatedPlayground; document.getElementById("id_title").value = toTitleCase(GTApiResponse.playgroundName); document.getElementById("id_description").value = GTApiResponse.playgroundDescription; - const tagElm = document.getElementById("id_tags"); - tagElm.value = tags; - if (tags.length > 1) { - tagElm.readOnly = true; - document.getElementById(tagElm.id + "Reason").textContent = "[Auto Completed as Exp Url is Provided]"; - } document.getElementById("id_no_players").value = GTApiResponse.mapRotation.maps[0].gameSize; { document.getElementById("id_no_bots").value = GTApiResponse.mapRotation.maps[0].gameSize; diff --git a/bfportal/core/helper.py b/bfportal/core/helper.py new file mode 100644 index 0000000..01b2900 --- /dev/null +++ b/bfportal/core/helper.py @@ -0,0 +1,26 @@ +import requests +from loguru import logger +from taggit.models import Tag + + +def get_tags_from_gt_api() -> list: + """Gets tags from GameTools api.""" + all_tags_json = requests.get( + "https://api.gametools.network/bf2042/availabletags/?lang=en-us" + ).json()["availableTags"] + return [ + tag_dict["metadata"]["translations"][0]["localizedText"] + for tag_dict in all_tags_json + ] + + +def save_tags_from_gt_api(): + """Saves non existing tags in db""" + tags_added = [] + for tag in get_tags_from_gt_api(): + if not Tag.objects.filter(name__exact=tag).exists(): + Tag(name=tag).save() + tags_added.append(tag) + else: + logger.debug(f"{tag} exists in db") + logger.debug(f"Added Tags :- {tags_added}") diff --git a/bfportal/core/management/commands/ensure_initialization.py b/bfportal/core/management/commands/ensure_initialization.py index 797c1a4..9a5a422 100644 --- a/bfportal/core/management/commands/ensure_initialization.py +++ b/bfportal/core/management/commands/ensure_initialization.py @@ -1,3 +1,4 @@ +from core.helper import save_tags_from_gt_api from core.models import ( ExperiencesCategory, ExperiencesPage, @@ -57,3 +58,5 @@ def handle(self, *args, **options): if not hasattr(user, "profile"): user.profile = Profile() user.save() + + save_tags_from_gt_api() diff --git a/bfportal/core/management/commands/portal.py b/bfportal/core/management/commands/portal.py index 8d97cb3..0762e73 100644 --- a/bfportal/core/management/commands/portal.py +++ b/bfportal/core/management/commands/portal.py @@ -1,7 +1,4 @@ -import json - -import requests -from core.models import AvailableTags +from core.helper import save_tags_from_gt_api from django.core.management import BaseCommand @@ -14,18 +11,9 @@ def add_arguments(self, parser): # noqa: D102 parser.add_argument( "--get_tags", action="store_true", - help="Gets all tags from game tools", + help="Gets all tags from game tools and saves to db", ) def handle(self, *args, **options): # noqa: D102 if options.get("get_tags", None): - all_tags_json = requests.get( - "https://api.gametools.network/bf2042/availabletags/?lang=en-us" - ).json()["availableTags"] - tags = [ - tag_dict["metadata"]["translations"][0]["localizedText"] - for tag_dict in all_tags_json - ] - AvailableTags.objects.all().delete() - new_obj = AvailableTags(tags=json.dumps(tags)) - new_obj.save() + save_tags_from_gt_api() diff --git a/bfportal/core/migrations/0051_delete_availabletags.py b/bfportal/core/migrations/0051_delete_availabletags.py new file mode 100644 index 0000000..8578e78 --- /dev/null +++ b/bfportal/core/migrations/0051_delete_availabletags.py @@ -0,0 +1,16 @@ +# Generated by Django 3.2.12 on 2022-09-20 10:42 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("core", "0050_auto_20220919_1727"), + ] + + operations = [ + migrations.DeleteModel( + name="AvailableTags", + ), + ] diff --git a/bfportal/core/models.py b/bfportal/core/models.py index 9814a11..0e51d02 100644 --- a/bfportal/core/models.py +++ b/bfportal/core/models.py @@ -638,9 +638,3 @@ def user_experiences(self, request, discord_id): ) else: return HttpResponse("User not Found", status=404) - - -class AvailableTags(models.Model): # noqa: D101 - tags = models.TextField( - blank=True, verbose_name="All available tags in BF 2042 Portal Rules editor" - ) diff --git a/bfportal/factory/management/commands/fake.py b/bfportal/factory/management/commands/fake.py index f3d0607..33e6722 100644 --- a/bfportal/factory/management/commands/fake.py +++ b/bfportal/factory/management/commands/fake.py @@ -3,6 +3,7 @@ from random import choice, choices, randint from uuid import uuid4 +from core.helper import get_tags_from_gt_api from core.models import ExperiencePage, ExperiencesCategory, ExperiencesPage from django.contrib.auth import get_user_model from django.core.management import BaseCommand @@ -51,7 +52,7 @@ def handle(self, *args, **options): owner = [ user for user in get_user_model().objects.all() if not user.is_superuser ] - tags = [factory.word() for i in range(20)] + tags = get_tags_from_gt_api() experiences_page = ExperiencesPage.objects.first() page_count = options.get("no_of_pages", [0])[0] logger.critical("delete all Experience Pages [y/n] ") diff --git a/bfportal/factory/management/commands/playground.py b/bfportal/factory/management/commands/playground.py index 6921f2f..48a325d 100644 --- a/bfportal/factory/management/commands/playground.py +++ b/bfportal/factory/management/commands/playground.py @@ -1,3 +1,4 @@ +from core.helper import get_tags_from_gt_api from django.core.management import BaseCommand @@ -5,4 +6,4 @@ class Command(BaseCommand): """Command that is used to develop other command and test stuff""" def handle(self, *args, **options): # noqa: D102 - print("pass") + print(get_tags_from_gt_api()) From bc6845e5974d9bd4ce0cbeeffe1ee92228db40f8 Mon Sep 17 00:00:00 2001 From: p0lygun Date: Tue, 20 Sep 2022 22:55:36 +0530 Subject: [PATCH 2/6] feat: wrap autocomplete input when deck gets full --- bfportal/core/templates/ajax_select/custom_base.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bfportal/core/templates/ajax_select/custom_base.html b/bfportal/core/templates/ajax_select/custom_base.html index 94add1d..743298b 100644 --- a/bfportal/core/templates/ajax_select/custom_base.html +++ b/bfportal/core/templates/ajax_select/custom_base.html @@ -1,8 +1,8 @@ -
-
- +
+
+
From 490479c4e83b57aff73c9d26f18d24ed695888b6 Mon Sep 17 00:00:00 2001 From: p0lygun Date: Tue, 20 Sep 2022 23:31:29 +0530 Subject: [PATCH 3/6] feat: load form css and js seperatly --- .../core/static/js/autocomplete_helper.js | 33 ++++++++++--------- .../templates/ajax_select/custom_base.html | 5 +-- .../core/submit_experience_page.html | 8 +++-- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/bfportal/core/static/js/autocomplete_helper.js b/bfportal/core/static/js/autocomplete_helper.js index 098bf0a..6eb9736 100644 --- a/bfportal/core/static/js/autocomplete_helper.js +++ b/bfportal/core/static/js/autocomplete_helper.js @@ -1,3 +1,19 @@ +function bindTriggers(html_id){ + const deck = $(`#${html_id}_on_deck`); + deck.bind('added', function () { + deck.children().last().show({ + duration: 100, + start: function () { + deck.children().last().css('display', 'flex') + } + }) + if(!deck.hasClass("ml-2")) deck.addClass("ml-2") + }) + deck.bind('killed', function () { + if(!deck.children().length) deck.removeClass("ml-2") + }) +} + defer(function initAutoCompleteHelper() { $(document).ready(function () { const autocompleteContainers = ["tags", "creators"] @@ -18,26 +34,11 @@ defer(function initAutoCompleteHelper() { input.focusout(function () { inputContainer.removeClass("border-1/2 border-bf2042-4") }) + bindTriggers(`id_${container}`) }) }) }) -function bindTriggers(html_id){ - const deck = $(`#${html_id}_on_deck`); - deck.bind('added', function () { - deck.children().last().show({ - duration: 100, - start: function () { - deck.children().last().css('display', 'flex') - } - }) - if(!deck.hasClass("ml-2")) deck.addClass("ml-2") - }) - deck.bind('killed', function () { - if(!deck.children().length) deck.removeClass("ml-2") - }) -} - function handleKeyDown(elm, event) { if (!elm.value && event.keyCode === 8) { const deck = $(`#${$(elm).parent().attr('id') === "tagsInputContainer" ? 'id_tags' : 'id_creators'}_on_deck`), diff --git a/bfportal/core/templates/ajax_select/custom_base.html b/bfportal/core/templates/ajax_select/custom_base.html index 743298b..e6a2172 100644 --- a/bfportal/core/templates/ajax_select/custom_base.html +++ b/bfportal/core/templates/ajax_select/custom_base.html @@ -1,13 +1,10 @@
-
+
-{% block extra_script %} - -{% endblock %} {% block help %}{% if help_text %}

{{ help_text }}

{% endif %}{% endblock %} diff --git a/bfportal/core/templates/core/submit_experience_page.html b/bfportal/core/templates/core/submit_experience_page.html index 5baa80a..2eeb9e1 100644 --- a/bfportal/core/templates/core/submit_experience_page.html +++ b/bfportal/core/templates/core/submit_experience_page.html @@ -2,11 +2,10 @@ {% load wagtailcore_tags widget_tweaks static %} {% block extra_css %} - {{ form.media }} + {{ form.media.css }} {% endblock %} {% block content %} -
@@ -164,3 +163,8 @@
{% endblock %} + +{% block extra_js %} + {{ form.media.js }} + +{% endblock %} From 777ad5ee5abe8463c24f305aeb7fce5cadd1b3d6 Mon Sep 17 00:00:00 2001 From: p0lygun Date: Wed, 21 Sep 2022 00:26:55 +0530 Subject: [PATCH 4/6] feat: load main css in body tag so that its loaded last --- bfportal/bfportal/templates/base.html | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/bfportal/bfportal/templates/base.html b/bfportal/bfportal/templates/base.html index 3f2a812..f34d3e1 100644 --- a/bfportal/bfportal/templates/base.html +++ b/bfportal/bfportal/templates/base.html @@ -51,17 +51,20 @@ + {% block preload_media %}{% endblock %} {% block extra_css %} {# Override this in templates to add extra stylesheets #} {% endblock %} - {# Global stylesheets #} - {% tailwind_css %} +{#Adding main css here so that its loded last#} +{% tailwind_css %} + + {% block header %} {% include nav_tmpl|default:'navbar.html' %} {% endblock %} From d421705ec698262284015df512bf155c6bf38b40 Mon Sep 17 00:00:00 2001 From: p0lygun Date: Wed, 21 Sep 2022 00:36:09 +0530 Subject: [PATCH 5/6] feat: increase specificity for autocomplete dropdown --- bfportal/bfportal/templates/base.html | 6 +----- bfportal/theme/static_src/src/styles.css | 6 +++--- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/bfportal/bfportal/templates/base.html b/bfportal/bfportal/templates/base.html index f34d3e1..96d0daa 100644 --- a/bfportal/bfportal/templates/base.html +++ b/bfportal/bfportal/templates/base.html @@ -56,15 +56,11 @@ {# Override this in templates to add extra stylesheets #} {% endblock %} + {% tailwind_css %} - -{#Adding main css here so that its loded last#} -{% tailwind_css %} - - {% block header %} {% include nav_tmpl|default:'navbar.html' %} {% endblock %} diff --git a/bfportal/theme/static_src/src/styles.css b/bfportal/theme/static_src/src/styles.css index c83c263..5541558 100644 --- a/bfportal/theme/static_src/src/styles.css +++ b/bfportal/theme/static_src/src/styles.css @@ -86,7 +86,7 @@ body::-webkit-scrollbar-thumb:hover { } } -.ui-widget.ui-widget-content { +ul.ui-widget.ui-widget-content { background-color: theme('colors.card-bg'); color: white; border: 0; @@ -97,11 +97,11 @@ body::-webkit-scrollbar-thumb:hover { color: white; } -.ui-menu-item-wrapper span { +a.ui-menu-item-wrapper span { color: white; } -.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active, a.ui-button:active, .ui-button:active, .ui-button.ui-state-active:hover { +a.ui-menu-item-wrapper.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active, a.ui-button:active, .ui-button:active, .ui-button.ui-state-active:hover { background: theme("colors.hover-bg-light"); border: 0; From 78d80fa3685680c58ebf4dbf4dc52fc2f097efb9 Mon Sep 17 00:00:00 2001 From: p0lygun Date: Wed, 21 Sep 2022 17:34:43 +0530 Subject: [PATCH 6/6] feat: add api to add tags to deck dynamically --- bfportal/bfportal/static/js/bfportal.js | 6 +-- .../core/static/js/autocomplete_helper.js | 52 +++++++++++++++++-- 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/bfportal/bfportal/static/js/bfportal.js b/bfportal/bfportal/static/js/bfportal.js index 1bcf0a0..a2ebe07 100644 --- a/bfportal/bfportal/static/js/bfportal.js +++ b/bfportal/bfportal/static/js/bfportal.js @@ -1,3 +1,5 @@ +// https://portal.battlefield.com/experience/package/era?playgroundId=d23be170-33aa-11ed-98f8-9d6912d338ca + $(document).ready(function() { "use strict"; $("body").on('click touch', function (event) { @@ -55,9 +57,7 @@ $(document).ready(function() { GTApiResponse.playgroundName = String; GTApiResponse.playgroundDescription = String; if (!GTApiResponse.hasOwnProperty('errors')) { - GTApiResponse.tag.forEach(elm => { - - }); + GTApiResponse.tag.forEach(elm => {addTagToDeck(elm['metadata']['translations'][0]['localizedText'])}); GTApiResponse = GTApiResponse.validatedPlayground; diff --git a/bfportal/core/static/js/autocomplete_helper.js b/bfportal/core/static/js/autocomplete_helper.js index 6eb9736..6ace838 100644 --- a/bfportal/core/static/js/autocomplete_helper.js +++ b/bfportal/core/static/js/autocomplete_helper.js @@ -1,4 +1,4 @@ -function bindTriggers(html_id){ +function bindTriggers(html_id) { const deck = $(`#${html_id}_on_deck`); deck.bind('added', function () { deck.children().last().show({ @@ -7,13 +7,55 @@ function bindTriggers(html_id){ deck.children().last().css('display', 'flex') } }) - if(!deck.hasClass("ml-2")) deck.addClass("ml-2") + if (!deck.hasClass("ml-2")) deck.addClass("ml-2") }) deck.bind('killed', function () { - if(!deck.children().length) deck.removeClass("ml-2") + if (!deck.children().length) deck.removeClass("ml-2") }) } +function addTagToDeck(tagName) { + fetch(`/ajax_select/ajax_lookup/tags?term=${tagName}`).then( + resp => resp.json().then(json => { + return addTag(json[0]) + }) + ) + function addTag(tag){ + const pk = tag.pk, + id = "id_tags", + $deck = $("#id_tags_on_deck"), + $text = $("#id_tags_text"), + $this = $('#id_tags'), + prev = $this.val(); + + if (prev.indexOf('|' + pk + '|') === -1) { + $this.val((prev ? prev : '|') + pk + '|'); + addKiller(tag.repr, pk); + $text.val(''); + $deck.trigger('added', [tag.pk, tag]); + $this.trigger('change'); + } + + function addKiller(repr, pk) { + const killId = 'kill_' + pk + id, + killButton = 'X '; + $deck.append('
' + killButton + repr + '
'); + + $('#' + killId).click(function () { + kill(pk); + $deck.trigger('killed', [pk]); + }); + } + + function kill(pk) { + $this.val($this.val().replace('|' + pk + '|', '|')); + $('#' + id + '_on_deck_' + pk).fadeOut().remove(); + } + return false; + } +} + + defer(function initAutoCompleteHelper() { $(document).ready(function () { const autocompleteContainers = ["tags", "creators"] @@ -22,8 +64,8 @@ defer(function initAutoCompleteHelper() { const input = $(`#id_${container}_text`), inputContainer = $(`#${container}InputContainer`), deck = $(`#id_${container}_on_deck`); - if(deck.children().length){ - if(!deck.hasClass("ml-2")) deck.addClass("ml-2") + if (deck.children().length) { + if (!deck.hasClass("ml-2")) deck.addClass("ml-2") deck.children().each(function () { $(this).css('display', 'flex') })