From d5d9b90b8df929745d339d3d38226a16cc6fac13 Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Sun, 23 May 2021 10:39:29 +0200 Subject: Add GoodReads CSS. --- pydis_site/static/css/resources/resources_list.css | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'pydis_site/static/css') diff --git a/pydis_site/static/css/resources/resources_list.css b/pydis_site/static/css/resources/resources_list.css index 33129c87..e6808a99 100644 --- a/pydis_site/static/css/resources/resources_list.css +++ b/pydis_site/static/css/resources/resources_list.css @@ -34,12 +34,12 @@ i.resource-icon.is-youtube-red:hover { color: #f80000; } -i.resource-icon.is-amazon-orange { - color: #FF9900; +i.resource-icon.is-goodreads-cream { + color: #f3f2e9; } -i.resource-icon.is-amazon-orange:hover { - color: #ffb71a; +i.resource-icon.is-goodreads-cream:hover { + color: #ffffff; } i.resource-icon.is-black { -- cgit v1.2.3 From c781ed1f80188ffb274eeada974172f4aa07c0b5 Mon Sep 17 00:00:00 2001 From: fisher60 Date: Fri, 23 Jul 2021 20:20:10 -0500 Subject: change resources to prepare for smart resource search --- pydis_site/apps/resources/urls.py | 2 +- pydis_site/apps/resources/views/__init__.py | 4 +- pydis_site/apps/resources/views/resources.py | 10 +- pydis_site/static/css/resources/resources.css | 51 +++++----- pydis_site/templates/resources/resources.html | 131 ++++++++++++++------------ 5 files changed, 105 insertions(+), 93 deletions(-) (limited to 'pydis_site/static/css') diff --git a/pydis_site/apps/resources/urls.py b/pydis_site/apps/resources/urls.py index cd4f53e7..c8d441df 100644 --- a/pydis_site/apps/resources/urls.py +++ b/pydis_site/apps/resources/urls.py @@ -4,6 +4,6 @@ from pydis_site.apps.resources import views app_name = "resources" urlpatterns = [ - path("", views.ResourcesView.as_view(), name="index"), + path("", views.resources.resource_view, name="index"), path("list/", views.ResourcesListView.as_view(), name="resources") ] diff --git a/pydis_site/apps/resources/views/__init__.py b/pydis_site/apps/resources/views/__init__.py index 8eb383b5..c89071c5 100644 --- a/pydis_site/apps/resources/views/__init__.py +++ b/pydis_site/apps/resources/views/__init__.py @@ -1,4 +1,4 @@ -from .resources import ResourcesView +from .resources import resource_view from .resources_list import ResourcesListView -__all__ = ["ResourcesView", "ResourcesListView"] +__all__ = ["resource_view", "ResourcesListView"] diff --git a/pydis_site/apps/resources/views/resources.py b/pydis_site/apps/resources/views/resources.py index 25ce3e50..dfd21682 100644 --- a/pydis_site/apps/resources/views/resources.py +++ b/pydis_site/apps/resources/views/resources.py @@ -1,7 +1,11 @@ from django.views.generic import TemplateView +from django.shortcuts import render +# class ResourcesView(TemplateView): +# """View for resources index page.""" +# +# template_name = "resources/resources.html" -class ResourcesView(TemplateView): - """View for resources index page.""" - template_name = "resources/resources.html" +def resource_view(request): + return render(request, template_name="resources/resources.html") diff --git a/pydis_site/static/css/resources/resources.css b/pydis_site/static/css/resources/resources.css index cf4cb472..a9226647 100644 --- a/pydis_site/static/css/resources/resources.css +++ b/pydis_site/static/css/resources/resources.css @@ -1,29 +1,30 @@ -.box, .tile.is-parent { - transition: 0.1s ease-out; -} -.box { - min-height: 15vh; -} -.tile.is-parent:hover .box { - box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23); -} -.tile.is-parent:hover { - padding: 0.65rem 0.85rem 0.85rem 0.65rem; - filter: saturate(1.1) brightness(1.1); -} +/*.box, .tile.is-parent {*/ +/* transition: 0.1s ease-out;*/ +/*}*/ +/*.box {*/ +/* min-height: 15vh;*/ +/*}*/ +/*.tile.is-parent:hover .box {*/ +/* box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23);*/ +/*}*/ +/*.tile.is-parent:hover {*/ +/* padding: 0.65rem 0.85rem 0.85rem 0.65rem;*/ +/* filter: saturate(1.1) brightness(1.1);*/ +/*}*/ -#readingBlock { - background-image: linear-gradient(141deg, #911eb4 0%, #b631de 71%, #cf4bf7 100%); -} +/*#readingBlock {*/ +/* background-image: linear-gradient(141deg, #911eb4 0%, #b631de 71%, #cf4bf7 100%);*/ +/*}*/ -#interactiveBlock { - background-image: linear-gradient(141deg, #d05600 0%, #da722a 71%, #e68846 100%); -} +/*#interactiveBlock {*/ +/* background-image: linear-gradient(141deg, #d05600 0%, #da722a 71%, #e68846 100%);*/ +/*}*/ -#communitiesBlock { - background-image: linear-gradient(141deg, #3b756f 0%, #3a847c 71%, #41948b 100%); -} +/*#communitiesBlock {*/ +/* background-image: linear-gradient(141deg, #3b756f 0%, #3a847c 71%, #41948b 100%);*/ +/*}*/ + +/*#podcastsBlock {*/ +/* background-image: linear-gradient(141deg, #232382 0%, #30309c 71%, #4343ad 100%);*/ +/*}*/ -#podcastsBlock { - background-image: linear-gradient(141deg, #232382 0%, #30309c 71%, #4343ad 100%); -} diff --git a/pydis_site/templates/resources/resources.html b/pydis_site/templates/resources/resources.html index 04744f90..7eb21432 100644 --- a/pydis_site/templates/resources/resources.html +++ b/pydis_site/templates/resources/resources.html @@ -12,79 +12,86 @@
-

Resources

+

Resources

+
+
+
+ {% endblock %} -- cgit v1.2.3 From a4d0139215b29058d0f8de17f389d589dafed34c Mon Sep 17 00:00:00 2001 From: swfarnsworth Date: Sat, 24 Jul 2021 20:32:34 -0400 Subject: Remove extra newline from end of file (there is now one newline). --- pydis_site/static/css/resources/resources.css | 1 - 1 file changed, 1 deletion(-) (limited to 'pydis_site/static/css') diff --git a/pydis_site/static/css/resources/resources.css b/pydis_site/static/css/resources/resources.css index a9226647..488effc3 100644 --- a/pydis_site/static/css/resources/resources.css +++ b/pydis_site/static/css/resources/resources.css @@ -27,4 +27,3 @@ /*#podcastsBlock {*/ /* background-image: linear-gradient(141deg, #232382 0%, #30309c 71%, #4343ad 100%);*/ /*}*/ - -- cgit v1.2.3 From 1dbe8046c38d43bc87fe6a78b1bfc61a3599de01 Mon Sep 17 00:00:00 2001 From: dawnofmidnight Date: Tue, 3 Aug 2021 14:53:17 -0400 Subject: styles: filtering resources page --- pydis_site/apps/resources/utils.py | 2 +- pydis_site/static/css/resources/resources_list.css | 9 ++++++ pydis_site/templates/resources/resources.html | 34 ++++++++++------------ 3 files changed, 25 insertions(+), 20 deletions(-) (limited to 'pydis_site/static/css') diff --git a/pydis_site/apps/resources/utils.py b/pydis_site/apps/resources/utils.py index 623dd7b6..bc444df4 100644 --- a/pydis_site/apps/resources/utils.py +++ b/pydis_site/apps/resources/utils.py @@ -21,7 +21,7 @@ RESOURCES: dict[str, Resource] = {path.stem: yaml.safe_load(path.read_text()) fo RESOURCE_TABLE = {category: defaultdict(set) for category in ( "topics", - "payment_tiers", + "payment_tiers", "complexity", "type" )} diff --git a/pydis_site/static/css/resources/resources_list.css b/pydis_site/static/css/resources/resources_list.css index e6808a99..283a506b 100644 --- a/pydis_site/static/css/resources/resources_list.css +++ b/pydis_site/static/css/resources/resources_list.css @@ -53,3 +53,12 @@ i.resource-icon.is-black { i.has-icon-padding { padding: 0 10px 25px 0; } + +#tab-content p { + display: none; +} + +#tab-content p.is-active { +display: block; +} + \ No newline at end of file diff --git a/pydis_site/templates/resources/resources.html b/pydis_site/templates/resources/resources.html index f2d5a976..8105a557 100644 --- a/pydis_site/templates/resources/resources.html +++ b/pydis_site/templates/resources/resources.html @@ -17,58 +17,58 @@

Resources


-
+

Search Options

-
- Topic +
+
Topic
{% for topic in topics %}
-
{% endfor %}
-
- Type +
+
Type
{% for tag_type in tag_types %}
{% endfor %}
-
- Payment +
+
Payment
{% for payment_tier in payment_tiers %}
{% endfor %}
-
- Level +
+
Level
{% for complexity in complexities %}
{% endfor %} @@ -76,7 +76,6 @@
- @@ -84,12 +83,9 @@ -
-
-
{% if resources|length > 0 %} @@ -120,7 +116,7 @@
{% else %} -

No resources matching search.

+

No resources matching search.

{% endif %} + + + {% endblock %} {% block content %} {% include "base/navbar.html" %} - -
-
+ {% if resources|length > 0 %} +
+ {# Headline #}

Resources


-
-

Search Options

- -
-
-
-
Topic
-
-
- {% for topic in topics_1 %} -
- -
- {% endfor %} -
-
- {% for topic in topics_2 %} -
- -
- {% endfor %} -
-
- - - -
-
-
Type
+
+ {# Filtering toolbox #} +
+
+ +
+
- {% for payment_tier in payment_tiers %} -
- -
+ {# Actual resources #} +
+
+
+ {% for resource in resources.values %} + {% include "resources/resource_box.html" %} {% endfor %} - - - -
-
-
Level
+ {% for subcategory in subcategories %} +

+ + {{ subcategory.category_info.name }} + +

+

{{ subcategory.category_info.description|safe }}

- {% for complexity in complexities %} -
- -
- {% endfor %} - - - + {% for resource in subcategory.resources %} + {% with category_info=subcategory.category_info %} + {% include "resources/resource_box.html" %} + {% endwith %} + {% endfor %} + {% endfor %}
- -
- - - - - - - -
-
-
-
- - {% if resources|length > 0 %} -
-
-
-
- {% for resource in resources %} - {% include "resources/resource_box.html" %} - {% endfor %} - - {% for subcategory in subcategories %} -

- - {{ subcategory.category_info.name }} - -

-

{{ subcategory.category_info.description|safe }}

- - {% for resource in subcategory.resources %} - {% with category_info=subcategory.category_info %} - {% include "resources/resource_box.html" %} - {% endwith %} - {% endfor %} - {% endfor %}
-
-
+
{% else %} -

No resources matching search.

+

No resources matching search.

{% endif %} {% endblock %} -- cgit v1.2.3 From da706784eef24e5b7bb45b50e2ebc1d8dd163a6c Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Fri, 28 Jan 2022 00:53:24 +0100 Subject: Make all tags interactive. Adds a bunch of tag-related quality of life improvements: - You can now see which filters you've added at the top left. - You can click on tags to start filtering to that tag. - You can click on tags in the filter box to remove the filter. - Tags will now show an outline when they are active. --- pydis_site/static/css/resources/resources.css | 91 +++++++++++++++++ pydis_site/static/js/resources.js | 123 +++++++++++++++++------ pydis_site/templates/resources/resource_box.html | 37 ++++++- pydis_site/templates/resources/resources.html | 123 ++++++++++++++++------- 4 files changed, 300 insertions(+), 74 deletions(-) (limited to 'pydis_site/static/css') diff --git a/pydis_site/static/css/resources/resources.css b/pydis_site/static/css/resources/resources.css index f70cbd64..c6347eab 100644 --- a/pydis_site/static/css/resources/resources.css +++ b/pydis_site/static/css/resources/resources.css @@ -25,3 +25,94 @@ i.is-primary { color: #7289da; } + +/* A little space around the filter card, please! */ +.filter-tags { + padding-bottom: .5em; + padding-right: .5em; +} + +/* Set default display to inline-flex, for centering. */ +span.filter-box-tag { + display: inline-flex; + align-items: center; + cursor: pointer; + user-select: none; +} + +/* Make resource tags clickable */ +.resource-tag { + cursor: pointer; + user-select: none; +} + +/* Move the x down 1 pixel to align center */ +button.delete { + margin-top: 1px; +} + +/* Colors for delete button x's */ +button.delete.is-primary::before, +button.delete.is-primary::after { + background-color: #2a45a2; +} +button.delete.is-success::before, +button.delete.is-success::after { + background-color: #2c9659; +} +button.delete.is-danger::before, +button.delete.is-danger::after { + background-color: #c32841; +} +button.delete.is-info::before, +button.delete.is-info::after { + background-color: #237fbd; +} + +/* Give outlines to active tags */ +span.filter-box-tag, +span.resource-tag.active { + outline-width: 1px; + outline-style: solid; +} + +/* Make filter tags sparkle when selected! */ +@keyframes glow_success { + from { box-shadow: 0 0 2px 2px #aef4af; } + 33% { box-shadow: 0 0 2px 2px #87af7a; } + 66% { box-shadow: 0 0 2px 2px #9ceaac; } + to { box-shadow: 0 0 2px 2px #7cbf64; } +} + +@keyframes glow_primary { + from { box-shadow: 0 0 2px 2px #aeb8f3; } + 33% { box-shadow: 0 0 2px 2px #909ed9; } + 66% { box-shadow: 0 0 2px 2px #6d7ed4; } + to { box-shadow: 0 0 2px 2px #6383b3; } +} + +@keyframes glow_danger { + from { box-shadow: 0 0 2px 2px #c9495f; } + 33% { box-shadow: 0 0 2px 2px #92486f; } + 66% { box-shadow: 0 0 2px 2px #d455ba; } + to { box-shadow: 0 0 2px 2px #ff8192; } +} +@keyframes glow_info { + from { box-shadow: 0 0 2px 2px #4592c9; } + 33% { box-shadow: 0 0 2px 2px #6196bb; } + 66% { box-shadow: 0 0 2px 2px #5adade; } + to { box-shadow: 0 0 2px 2px #6bcfdc; } +} + +span.resource-tag.active.is-primary { + animation: glow_primary 4s infinite alternate; +} +span.resource-tag.active.has-background-danger-light { + animation: glow_danger 4s infinite alternate; +} +span.resource-tag.active.has-background-success-light { + animation: glow_success 4s infinite alternate; +} +span.resource-tag.active.has-background-info-light { + animation: glow_info 4s infinite alternate; +} diff --git a/pydis_site/static/js/resources.js b/pydis_site/static/js/resources.js index 836ef4ec..c9ce408b 100644 --- a/pydis_site/static/js/resources.js +++ b/pydis_site/static/js/resources.js @@ -8,6 +8,37 @@ var activeFilters = { complexity: [] }; +function addFilter(filterName, filterItem) { + // Push the filter into the stack + var filterIndex = activeFilters[filterName].indexOf(filterItem); + if (filterIndex === -1) { + activeFilters[filterName].push(filterItem); + } + updateUI(); + + // Show a corresponding filter box tag + $(`.filter-box-tag[data-filter-name=${filterName}][data-filter-item=${filterItem}]`).show(); + $(".filter-tags").css("padding-bottom", "0.5em"); + + // Make corresponding resource tags active + $(`.resource-tag[data-filter-name=${filterName}][data-filter-item=${filterItem}]`).addClass("active"); +} + +function removeFilter(filterName, filterItem) { + // Remove the filter from the stack + var filterIndex = activeFilters[filterName].indexOf(filterItem); + if (filterIndex !== -1) { + activeFilters[filterName].splice(filterIndex, 1); + } + updateUI(); + + // Hide the corresponding filter box tag + $(`.filter-box-tag[data-filter-name=${filterName}][data-filter-item=${filterItem}]`).hide(); + + // Make corresponding resource tags inactive + $(`.resource-tag[data-filter-name=${filterName}][data-filter-item=${filterItem}]`).removeClass("active"); +} + /* Check if there are no filters */ function noFilters() { return ( @@ -18,26 +49,6 @@ function noFilters() { ); } -/* Update the URL with new parameters */ -function updateURL() { - // If there's nothing in the filters, we don't want anything in the URL. - if (noFilters()) { - window.history.replaceState(null, document.title, './'); - return; - } - - // Iterate through and get rid of empty ones - let searchParams = new URLSearchParams(activeFilters); - $.each(activeFilters, function(filterType, filters) { - if (filters.length === 0) { - searchParams.delete(filterType); - } - }); - - // Now update the URL - window.history.replaceState(null, document.title, `?${searchParams.toString()}`); -} - /* Get the params out of the URL and use them. This is run when the page loads. */ function deserializeURLParams() { let searchParams = new window.URLSearchParams(window.location.search); @@ -51,18 +62,43 @@ function deserializeURLParams() { let paramFilterArray = paramFilterContent.split(","); activeFilters[filterType] = paramFilterArray; - // Check corresponding checkboxes, so the UI reflects the internal state. + // Update the corresponding filter UI, so it reflects the internal state. $(paramFilterArray).each(function(_, filter) { let checkbox = $(`.filter-checkbox[data-filter-name=${filterType}][data-filter-item=${filter}]`); + let filterTag = $(`.filter-box-tag[data-filter-name=${filterType}][data-filter-item=${filter}]`); + let resourceTags = $(`.resource-tag[data-filter-name=${filterType}][data-filter-item=${filter}]`); checkbox.prop("checked", true); + filterTag.show(); + resourceTags.addClass("active"); }); } }); } +/* Update the URL with new parameters */ +function updateURL() { + // If there's nothing in the filters, we don't want anything in the URL. + if (noFilters()) { + window.history.replaceState(null, document.title, './'); + return; + } + + // Iterate through and get rid of empty ones + let searchParams = new URLSearchParams(activeFilters); + $.each(activeFilters, function(filterType, filters) { + if (filters.length === 0) { + searchParams.delete(filterType); + } + }); + + // Now update the URL + window.history.replaceState(null, document.title, `?${searchParams.toString()}`); +} + /* Update the resources to match 'active_filters' */ -function update() { +function updateUI() { let resources = $('.resource-box'); + let filterTags = $('.filter-box-tag'); // Update the URL to match the new filters. updateURL(); @@ -70,6 +106,8 @@ function update() { // If there's nothing in the filters, show everything and return. if (noFilters()) { resources.show(); + filterTags.hide(); + $(".filter-tags").css("padding-bottom", "0"); return; } @@ -112,8 +150,9 @@ function update() { // Executed when the page has finished loading. document.addEventListener("DOMContentLoaded", function () { // Update the filters on page load to reflect URL parameters. + $('.filter-box-tag').hide(); deserializeURLParams(); - update(); + updateUI(); // If you collapse or uncollapse a filter group, swap the icon. $('button.collapsible').click(function() { @@ -128,29 +167,47 @@ document.addEventListener("DOMContentLoaded", function () { } }); - // If you click on the div surrounding the filter checkbox, it clicks the checkbox. + // If you click on the div surrounding the filter checkbox, it clicks the corresponding checkbox. $('.filter-panel').click(function() { let checkbox = $(this).find(".filter-checkbox"); checkbox.prop("checked", !checkbox.prop("checked")); checkbox.change(); }); + // If you click on one of the tags in the filter box, it unchecks the corresponding checkbox. + $('.filter-box-tag').click(function() { + let filterItem = this.dataset.filterItem; + let filterName = this.dataset.filterName; + let checkbox = $(`.filter-checkbox[data-filter-name=${filterName}][data-filter-item=${filterItem}]`); + + removeFilter(filterName, filterItem); + checkbox.prop("checked", false); + }); + + // If you click on one of the tags in the resource cards, it clicks the corresponding checkbox. + $('.resource-tag').click(function() { + let filterItem = this.dataset.filterItem; + let filterName = this.dataset.filterName; + let checkbox = $(`.filter-checkbox[data-filter-name=${filterName}][data-filter-item=${filterItem}]`) + + if (!$(this).hasClass("active")) { + addFilter(filterName, filterItem); + checkbox.prop("checked", true); + } else { + removeFilter(filterName, filterItem); + checkbox.prop("checked", false); + } + }); + // When checkboxes are toggled, trigger a filter update. $('.filter-checkbox').change(function () { let filterItem = this.dataset.filterItem; let filterName = this.dataset.filterName; - var filterIndex = activeFilters[filterName].indexOf(filterItem); if (this.checked) { - if (filterIndex === -1) { - activeFilters[filterName].push(filterItem); - } - update(); + addFilter(filterName, filterItem); } else { - if (filterIndex !== -1) { - activeFilters[filterName].splice(filterIndex, 1); - } - update(); + removeFilter(filterName, filterItem); } }); }); diff --git a/pydis_site/templates/resources/resource_box.html b/pydis_site/templates/resources/resource_box.html index 09256751..476a4841 100644 --- a/pydis_site/templates/resources/resource_box.html +++ b/pydis_site/templates/resources/resource_box.html @@ -1,4 +1,5 @@ {% load as_icon %} +{% load as_css_class %} {% load get_category_icon %}
@@ -34,16 +35,44 @@ {# Tags #}
{% for tag in resource.tags.topics %} - {{ tag|title }} + + + {{ tag|title }} + {% endfor %} {% for tag in resource.tags.type %} - {{ tag|title }} + + + {{ tag|title }} + {% endfor %} {% for tag in resource.tags.payment_tiers %} - {{ tag|title }} + + + {{ tag|title }} + {% endfor %} {% for tag in resource.tags.complexity %} - {{ tag|title }} + + + {{ tag|title }} + {% endfor %}
diff --git a/pydis_site/templates/resources/resources.html b/pydis_site/templates/resources/resources.html index 134c826b..87c28153 100644 --- a/pydis_site/templates/resources/resources.html +++ b/pydis_site/templates/resources/resources.html @@ -1,74 +1,123 @@ {% extends 'base/base.html' %} {% load as_icon %} {% load as_css_class %} +{% load get_category_icon %} {% load static %} {% block title %}Resources{% endblock %} {% block head %} - - - + + + {% endblock %} {% block content %} {% include "base/navbar.html" %} {% if resources|length > 0 %}
- {# Headline #} -
-

Resources

-
-
-
{# Filtering toolbox #}
-- cgit v1.2.3 From 72ca8758da4b80b638a83093a35a031210a8d9f2 Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Sat, 29 Jan 2022 12:39:21 +0100 Subject: Let the user know when there are no matches. --- pydis_site/static/css/resources/resources.css | 6 + pydis_site/static/js/resources.js | 11 ++ pydis_site/templates/resources/resources.html | 162 ++++++++++++-------------- 3 files changed, 91 insertions(+), 88 deletions(-) (limited to 'pydis_site/static/css') diff --git a/pydis_site/static/css/resources/resources.css b/pydis_site/static/css/resources/resources.css index c6347eab..218d9a59 100644 --- a/pydis_site/static/css/resources/resources.css +++ b/pydis_site/static/css/resources/resources.css @@ -15,6 +15,12 @@ padding:0 } +/* Hide the no resources h2 by default */ +h2.no-resources-found { + display: none; + margin-top: 1em; +} + /* Disable clicking on the checkbox itself. */ /* Instead, we want to let the anchor tag handle clicks. */ .filter-checkbox { diff --git a/pydis_site/static/js/resources.js b/pydis_site/static/js/resources.js index c9ce408b..89b8ae06 100644 --- a/pydis_site/static/js/resources.js +++ b/pydis_site/static/js/resources.js @@ -112,6 +112,8 @@ function updateUI() { } // Otherwise, hide everything and then filter the resources to decide what to show. + let hasMatches = false; + console.log(hasMatches); resources.hide(); resources.filter(function() { let validation = { @@ -140,11 +142,20 @@ function updateUI() { // If validation passes, show the resource. if (Object.values(validation).every(Boolean)) { + hasMatches = true; return true; } else { return false; } }).show(); + + // If there are no matches, show the no matches message + console.log(hasMatches); + if (!hasMatches) { + $(".no-resources-found").show(); + } else { + $(".no-resources-found").hide(); + } } // Executed when the page has finished loading. diff --git a/pydis_site/templates/resources/resources.html b/pydis_site/templates/resources/resources.html index 87c28153..b82f16e1 100644 --- a/pydis_site/templates/resources/resources.html +++ b/pydis_site/templates/resources/resources.html @@ -16,141 +16,127 @@ {% block content %} {% include "base/navbar.html" %} - {% if resources|length > 0 %} -
-
- {# Filtering toolbox #} -
-
-
+ {% endfor %} +
+
- {# Actual resources #} -
-
-
- {% for resource in resources.values %} - {% include "resources/resource_box.html" %} - {% endfor %} - - {% for subcategory in subcategories %} -

- - {{ subcategory.category_info.name }} - -

-

{{ subcategory.category_info.description|safe }}

+
+ {# Message to display when there are no hits #} +

No matching resources found!

- {% for resource in subcategory.resources %} - {% with category_info=subcategory.category_info %} - {% include "resources/resource_box.html" %} - {% endwith %} - {% endfor %} - {% endfor %} -
+ {# Resource cards #} +
+
+ {% for resource in resources.values %} + {% include "resources/resource_box.html" %} + {% endfor %}
-
- {% else %} -

No resources matching search.

- {% endif %} +

+
{% endblock %} + + -- cgit v1.2.3 From 783bb2af9c5b5940f0fa2d3a0d0cbd34ec7e1316 Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Sat, 29 Jan 2022 12:58:10 +0100 Subject: Don't round edges of the filter category headers. --- pydis_site/static/css/resources/resources.css | 5 +++++ pydis_site/templates/resources/resources.html | 26 +++++++++++++------------- 2 files changed, 18 insertions(+), 13 deletions(-) (limited to 'pydis_site/static/css') diff --git a/pydis_site/static/css/resources/resources.css b/pydis_site/static/css/resources/resources.css index 218d9a59..db083a41 100644 --- a/pydis_site/static/css/resources/resources.css +++ b/pydis_site/static/css/resources/resources.css @@ -15,6 +15,11 @@ padding:0 } +/* Don't round the corners of the collapsibles */ +.filter-category-header { + border-radius: 0; +} + /* Hide the no resources h2 by default */ h2.no-resources-found { display: none; diff --git a/pydis_site/templates/resources/resources.html b/pydis_site/templates/resources/resources.html index b82f16e1..411ae056 100644 --- a/pydis_site/templates/resources/resources.html +++ b/pydis_site/templates/resources/resources.html @@ -80,19 +80,19 @@ {# Filter checkboxes #} {% for filter_name, filter_data in filters.items %} -
- +
+ {# Checkboxes #} {% if filter_data.hidden %} -- cgit v1.2.3 From aa1420aeb91a9663a714cdceb0f957d9837740e7 Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Sun, 30 Jan 2022 12:33:20 +0100 Subject: Clean up hover effects. - We now have a hover effect for all icons. - We also now support hover effects for all tags. - However, we don't have any hover effect for icons in titles. That just looks weird. Additionally, we're getting rid of some bloat and consolidating the CSS into one place. --- pydis_site/static/css/resources/resources.css | 48 ++++++++++++++++++ pydis_site/static/css/resources/resources_list.css | 57 ---------------------- pydis_site/templates/resources/resource_box.html | 4 +- 3 files changed, 50 insertions(+), 59 deletions(-) delete mode 100644 pydis_site/static/css/resources/resources_list.css (limited to 'pydis_site/static/css') diff --git a/pydis_site/static/css/resources/resources.css b/pydis_site/static/css/resources/resources.css index db083a41..7038d0d7 100644 --- a/pydis_site/static/css/resources/resources.css +++ b/pydis_site/static/css/resources/resources.css @@ -1,3 +1,45 @@ +/* Colors for icons */ +i.resource-icon.is-orangered { + color: #FE640A; +} +i.resource-icon.is-blurple { + color: #7289DA; +} +i.resource-icon.is-teal { + color: #95DBE5; +} +i.resource-icon.is-youtube-red { + color: #BB0000; +} +i.resource-icon.is-black { + color: #2c3334; +} + +/* Colors when icons are hovered */ +i.resource-icon.is-hoverable:hover { + filter: brightness(125%); +} +i.resource-icon.is-hoverable.is-black:hover { + filter: brightness(170%); +} +i.resource-icon.is-hoverable.is-teal:hover { + filter: brightness(80%); +} + +/* Icon padding */ +.breadcrumb-section { + padding: 1rem; +} +i.has-icon-padding { + padding: 0 10px 25px 0; +} +#tab-content p { + display: none; +} +#tab-content p.is-active { +display: block; +} + /* Disable highlighting for all text in the filters. */ .filter-checkbox, .filter-panel label, @@ -57,6 +99,12 @@ span.filter-box-tag { user-select: none; } +/* When hovering tags, brighten them a bit. */ +.resource-tag:hover, +.filter-box-tag:hover { + filter: brightness(95%); +} + /* Move the x down 1 pixel to align center */ button.delete { margin-top: 1px; diff --git a/pydis_site/static/css/resources/resources_list.css b/pydis_site/static/css/resources/resources_list.css deleted file mode 100644 index c2151bee..00000000 --- a/pydis_site/static/css/resources/resources_list.css +++ /dev/null @@ -1,57 +0,0 @@ -.breadcrumb-section { - padding: 1rem; -} - -i.resource-icon.is-orangered { - color: #FE640A; -} - -i.resource-icon.is-orangered:hover { - color: #fe9840; -} - -i.resource-icon.is-blurple { - color: #7289DA; -} - -i.resource-icon.is-blurple:hover { - color: #93a8da; -} - -i.resource-icon.is-teal { - color: #95DBE5; -} - -i.resource-icon.is-teal:hover { - color: #a9f5ff; -} - -i.resource-icon.is-youtube-red { - color: #BB0000; -} - -i.resource-icon.is-youtube-red:hover { - color: #f80000; -} - -i.resource-icon.is-goodreads-cream, -i.resource-icon.is-black { - color: #2c3334; -} - -i.resource-icon.is-goodreads-cream:hover, -i.resource-icon.is-black:hover { - color: #475d6d; -} - -i.has-icon-padding { - padding: 0 10px 25px 0; -} - -#tab-content p { - display: none; -} - -#tab-content p.is-active { -display: block; -} diff --git a/pydis_site/templates/resources/resource_box.html b/pydis_site/templates/resources/resource_box.html index 8a1017b5..b06ffd31 100644 --- a/pydis_site/templates/resources/resource_box.html +++ b/pydis_site/templates/resources/resource_box.html @@ -18,7 +18,7 @@ {% if 'title_url' in resource %} - + {% endif %} @@ -27,7 +27,7 @@ {% for icon in resource.urls %} - + {% endfor %} -- cgit v1.2.3 From 2cbaeb129b793fa3dc162258dd4e60781e35d5f1 Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Sun, 30 Jan 2022 13:04:58 +0100 Subject: Show a duck pond when no filters match. --- pydis_site/static/css/resources/resources.css | 7 +++++++ pydis_site/static/images/resources/duck_pond_404.png | Bin 0 -> 2371374 bytes pydis_site/templates/resources/resources.html | 6 +++++- 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 pydis_site/static/images/resources/duck_pond_404.png (limited to 'pydis_site/static/css') diff --git a/pydis_site/static/css/resources/resources.css b/pydis_site/static/css/resources/resources.css index 7038d0d7..b48beca6 100644 --- a/pydis_site/static/css/resources/resources.css +++ b/pydis_site/static/css/resources/resources.css @@ -93,6 +93,13 @@ span.filter-box-tag { user-select: none; } +/* Center the 404 div */ +.no-resources-found { + display: flex; + flex-direction: column; + align-items: center; +} + /* Make resource tags clickable */ .resource-tag { cursor: pointer; diff --git a/pydis_site/static/images/resources/duck_pond_404.png b/pydis_site/static/images/resources/duck_pond_404.png new file mode 100644 index 00000000..3aed4d62 Binary files /dev/null and b/pydis_site/static/images/resources/duck_pond_404.png differ diff --git a/pydis_site/templates/resources/resources.html b/pydis_site/templates/resources/resources.html index 4dd07270..53feb255 100644 --- a/pydis_site/templates/resources/resources.html +++ b/pydis_site/templates/resources/resources.html @@ -124,7 +124,11 @@
{# Message to display when there are no hits #} -

No matching resources found!

+
+

No matching resources found!

+ +
+ {# Resource cards #}
-- cgit v1.2.3 From 295cd818e3d679083b962ee90e334ad4cbc9adba Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Sun, 30 Jan 2022 14:03:10 +0100 Subject: Fix broken css for no-resource duck pond. --- pydis_site/static/css/resources/resources.css | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'pydis_site/static/css') diff --git a/pydis_site/static/css/resources/resources.css b/pydis_site/static/css/resources/resources.css index b48beca6..aa47be8f 100644 --- a/pydis_site/static/css/resources/resources.css +++ b/pydis_site/static/css/resources/resources.css @@ -62,8 +62,15 @@ display: block; border-radius: 0; } +/* Center the 404 div */ +.no-resources-found { + display: flex; + flex-direction: column; + align-items: center; +} + /* Hide the no resources h2 by default */ -h2.no-resources-found { +.no-resources-found { display: none; margin-top: 1em; } @@ -93,13 +100,6 @@ span.filter-box-tag { user-select: none; } -/* Center the 404 div */ -.no-resources-found { - display: flex; - flex-direction: column; - align-items: center; -} - /* Make resource tags clickable */ .resource-tag { cursor: pointer; -- cgit v1.2.3 From dda3e355ac31dc4b9629f2e9e63474bbba69d740 Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Sun, 30 Jan 2022 14:29:48 +0100 Subject: Refactor: collapsibles as a stand-alone component --- pydis_site/apps/resources/urls.py | 1 + pydis_site/static/css/collapsibles.css | 12 ++ pydis_site/static/css/content/page.css | 13 -- pydis_site/static/js/collapsibles.js | 13 ++ pydis_site/static/js/content/page.js | 13 -- pydis_site/static/js/resources.js | 236 -------------------------- pydis_site/static/js/resources/resources.js | 236 ++++++++++++++++++++++++++ pydis_site/templates/content/base.html | 3 +- pydis_site/templates/resources/resources.html | 6 +- 9 files changed, 267 insertions(+), 266 deletions(-) create mode 100644 pydis_site/static/css/collapsibles.css create mode 100644 pydis_site/static/js/collapsibles.js delete mode 100644 pydis_site/static/js/content/page.js delete mode 100644 pydis_site/static/js/resources.js create mode 100644 pydis_site/static/js/resources/resources.js (limited to 'pydis_site/static/css') diff --git a/pydis_site/apps/resources/urls.py b/pydis_site/apps/resources/urls.py index aa3892b6..044f7072 100644 --- a/pydis_site/apps/resources/urls.py +++ b/pydis_site/apps/resources/urls.py @@ -31,6 +31,7 @@ VALID_RESOURCE_TYPES = [ def get_all_pages() -> typing.Iterator[dict[str, str]]: + """Get all the valid options for the resource_type path selector.""" for resource_type in VALID_RESOURCE_TYPES: yield {"resource_type": resource_type} diff --git a/pydis_site/static/css/collapsibles.css b/pydis_site/static/css/collapsibles.css new file mode 100644 index 00000000..7b76d8d5 --- /dev/null +++ b/pydis_site/static/css/collapsibles.css @@ -0,0 +1,12 @@ +.collapsible { + cursor: pointer; + width: 100%; + border: none; + outline: none; +} + +.collapsible-content { + overflow: hidden; + max-height: 0; + transition: max-height 0.2s ease-out; +} \ No newline at end of file diff --git a/pydis_site/static/css/content/page.css b/pydis_site/static/css/content/page.css index 2d4bd325..d831f86d 100644 --- a/pydis_site/static/css/content/page.css +++ b/pydis_site/static/css/content/page.css @@ -77,16 +77,3 @@ ul.menu-list.toc { li img { margin-top: 0.5em; } - -.collapsible { - cursor: pointer; - width: 100%; - border: none; - outline: none; -} - -.collapsible-content { - overflow: hidden; - max-height: 0; - transition: max-height 0.2s ease-out; -} diff --git a/pydis_site/static/js/collapsibles.js b/pydis_site/static/js/collapsibles.js new file mode 100644 index 00000000..366a033c --- /dev/null +++ b/pydis_site/static/js/collapsibles.js @@ -0,0 +1,13 @@ +document.addEventListener("DOMContentLoaded", () => { + const headers = document.getElementsByClassName("collapsible"); + for (const header of headers) { + header.addEventListener("click", () => { + var content = header.nextElementSibling; + if (content.style.maxHeight){ + content.style.maxHeight = null; + } else { + content.style.maxHeight = content.scrollHeight + "px"; + } + }); + } +}); diff --git a/pydis_site/static/js/content/page.js b/pydis_site/static/js/content/page.js deleted file mode 100644 index 366a033c..00000000 --- a/pydis_site/static/js/content/page.js +++ /dev/null @@ -1,13 +0,0 @@ -document.addEventListener("DOMContentLoaded", () => { - const headers = document.getElementsByClassName("collapsible"); - for (const header of headers) { - header.addEventListener("click", () => { - var content = header.nextElementSibling; - if (content.style.maxHeight){ - content.style.maxHeight = null; - } else { - content.style.maxHeight = content.scrollHeight + "px"; - } - }); - } -}); diff --git a/pydis_site/static/js/resources.js b/pydis_site/static/js/resources.js deleted file mode 100644 index 718e1e88..00000000 --- a/pydis_site/static/js/resources.js +++ /dev/null @@ -1,236 +0,0 @@ -"use strict"; - -// Filters that are currently selected -var activeFilters = { - topics: [], - type: [], - "payment-tiers": [], - difficulty: [] -}; - -function addFilter(filterName, filterItem) { - // Push the filter into the stack - var filterIndex = activeFilters[filterName].indexOf(filterItem); - if (filterIndex === -1) { - activeFilters[filterName].push(filterItem); - } - updateUI(); - - // Show a corresponding filter box tag - $(`.filter-box-tag[data-filter-name=${filterName}][data-filter-item=${filterItem}]`).show(); - - // Make corresponding resource tags active - $(`.resource-tag[data-filter-name=${filterName}][data-filter-item=${filterItem}]`).addClass("active"); - - // Hide the "No filters selected" tag. - $(".no-tags-selected.tag").hide(); -} - -function removeFilter(filterName, filterItem) { - // Remove the filter from the stack - var filterIndex = activeFilters[filterName].indexOf(filterItem); - if (filterIndex !== -1) { - activeFilters[filterName].splice(filterIndex, 1); - } - updateUI(); - - // Hide the corresponding filter box tag - $(`.filter-box-tag[data-filter-name=${filterName}][data-filter-item=${filterItem}]`).hide(); - - // Make corresponding resource tags inactive - $(`.resource-tag[data-filter-name=${filterName}][data-filter-item=${filterItem}]`).removeClass("active"); - - // Show "No filters selected" tag, if there are no filters active - if (noFilters()) { - $(".no-tags-selected.tag").show(); - } -} - -/* Check if there are no filters */ -function noFilters() { - return ( - activeFilters.topics.length === 0 && - activeFilters.type.length === 0 && - activeFilters["payment-tiers"].length === 0 && - activeFilters.difficulty.length === 0 - ); -} - -/* Get the params out of the URL and use them. This is run when the page loads. */ -function deserializeURLParams() { - let searchParams = new window.URLSearchParams(window.location.search); - - // Work through the parameters and add them to the filter object - $.each(Object.keys(activeFilters), function(_, filterType) { - let paramFilterContent = searchParams.get(filterType); - - if (paramFilterContent !== null) { - // We use split here because we always want an array, not a string. - let paramFilterArray = paramFilterContent.split(","); - activeFilters[filterType] = paramFilterArray; - - // Update the corresponding filter UI, so it reflects the internal state. - $(paramFilterArray).each(function(_, filter) { - let checkbox = $(`.filter-checkbox[data-filter-name='${filterType}'][data-filter-item='${filter}']`); - let filterTag = $(`.filter-box-tag[data-filter-name='${filterType}'][data-filter-item='${filter}']`); - let resourceTags = $(`.resource-tag[data-filter-name='${filterType}'][data-filter-item='${filter}']`); - checkbox.prop("checked", true); - filterTag.show(); - resourceTags.addClass("active"); - }); - } - }); -} - -/* Update the URL with new parameters */ -function updateURL() { - // If there's nothing in the filters, we don't want anything in the URL. - if (noFilters()) { - window.history.replaceState(null, document.title, './'); - return; - } - - // Iterate through and get rid of empty ones - let searchParams = new URLSearchParams(activeFilters); - $.each(activeFilters, function(filterType, filters) { - if (filters.length === 0) { - searchParams.delete(filterType); - } - }); - - // Now update the URL - window.history.replaceState(null, document.title, `?${searchParams.toString()}`); -} - -/* Update the resources to match 'active_filters' */ -function updateUI() { - let resources = $('.resource-box'); - let filterTags = $('.filter-box-tag'); - - // Update the URL to match the new filters. - updateURL(); - - // If there's nothing in the filters, show everything and return. - if (noFilters()) { - resources.show(); - filterTags.hide(); - return; - } - - // Otherwise, hide everything and then filter the resources to decide what to show. - let hasMatches = false; - resources.hide(); - resources.filter(function() { - let validation = { - topics: false, - type: false, - 'payment-tiers': false, - difficulty: false - }; - let resourceBox = $(this); - - // Validate the filters - $.each(activeFilters, function(filterType, filters) { - // If the filter list is empty, this passes validation. - if (filters.length === 0) { - validation[filterType] = true; - return; - } - - // Otherwise, we need to check if one of the classes exist. - $.each(filters, function(index, filter) { - if (resourceBox.hasClass(`${filterType}-${filter}`)) { - validation[filterType] = true; - } - }); - }); - - // If validation passes, show the resource. - if (Object.values(validation).every(Boolean)) { - hasMatches = true; - return true; - } else { - return false; - } - }).show(); - - // If there are no matches, show the no matches message - if (!hasMatches) { - $(".no-resources-found").show(); - } else { - $(".no-resources-found").hide(); - } -} - -// Executed when the page has finished loading. -document.addEventListener("DOMContentLoaded", function () { - /* Check if the user has navigated to one of the old resource pages, - like pydis.com/resources/communities. In this case, we'll rewrite - the URL before we do anything else. */ - let resourceTypeInput = $("#resource-type-input").val(); - if (resourceTypeInput !== "None") { - window.history.replaceState(null, document.title, `../?type=${resourceTypeInput}`); - } - - // Update the filters on page load to reflect URL parameters. - $('.filter-box-tag').hide(); - deserializeURLParams(); - updateUI(); - - // If you collapse or uncollapse a filter group, swap the icon. - $('button.collapsible').click(function() { - let icon = $(this).find(".card-header-icon i"); - - if ($(icon).hasClass("fa-window-minimize")) { - $(icon).removeClass(["far", "fa-window-minimize"]); - $(icon).addClass(["fas", "fa-angle-down"]); - } else { - $(icon).removeClass(["fas", "fa-angle-down"]); - $(icon).addClass(["far", "fa-window-minimize"]); - } - }); - - // If you click on the div surrounding the filter checkbox, it clicks the corresponding checkbox. - $('.filter-panel').click(function() { - let checkbox = $(this).find(".filter-checkbox"); - checkbox.prop("checked", !checkbox.prop("checked")); - checkbox.change(); - }); - - // If you click on one of the tags in the filter box, it unchecks the corresponding checkbox. - $('.filter-box-tag').click(function() { - let filterItem = this.dataset.filterItem; - let filterName = this.dataset.filterName; - let checkbox = $(`.filter-checkbox[data-filter-name='${filterName}'][data-filter-item='${filterItem}']`); - - removeFilter(filterName, filterItem); - checkbox.prop("checked", false); - }); - - // If you click on one of the tags in the resource cards, it clicks the corresponding checkbox. - $('.resource-tag').click(function() { - let filterItem = this.dataset.filterItem; - let filterName = this.dataset.filterName; - let checkbox = $(`.filter-checkbox[data-filter-name='${filterName}'][data-filter-item='${filterItem}']`); - - if (!$(this).hasClass("active")) { - addFilter(filterName, filterItem); - checkbox.prop("checked", true); - } else { - removeFilter(filterName, filterItem); - checkbox.prop("checked", false); - } - }); - - // When checkboxes are toggled, trigger a filter update. - $('.filter-checkbox').change(function () { - let filterItem = this.dataset.filterItem; - let filterName = this.dataset.filterName; - - if (this.checked) { - addFilter(filterName, filterItem); - } else { - removeFilter(filterName, filterItem); - } - }); -}); diff --git a/pydis_site/static/js/resources/resources.js b/pydis_site/static/js/resources/resources.js new file mode 100644 index 00000000..718e1e88 --- /dev/null +++ b/pydis_site/static/js/resources/resources.js @@ -0,0 +1,236 @@ +"use strict"; + +// Filters that are currently selected +var activeFilters = { + topics: [], + type: [], + "payment-tiers": [], + difficulty: [] +}; + +function addFilter(filterName, filterItem) { + // Push the filter into the stack + var filterIndex = activeFilters[filterName].indexOf(filterItem); + if (filterIndex === -1) { + activeFilters[filterName].push(filterItem); + } + updateUI(); + + // Show a corresponding filter box tag + $(`.filter-box-tag[data-filter-name=${filterName}][data-filter-item=${filterItem}]`).show(); + + // Make corresponding resource tags active + $(`.resource-tag[data-filter-name=${filterName}][data-filter-item=${filterItem}]`).addClass("active"); + + // Hide the "No filters selected" tag. + $(".no-tags-selected.tag").hide(); +} + +function removeFilter(filterName, filterItem) { + // Remove the filter from the stack + var filterIndex = activeFilters[filterName].indexOf(filterItem); + if (filterIndex !== -1) { + activeFilters[filterName].splice(filterIndex, 1); + } + updateUI(); + + // Hide the corresponding filter box tag + $(`.filter-box-tag[data-filter-name=${filterName}][data-filter-item=${filterItem}]`).hide(); + + // Make corresponding resource tags inactive + $(`.resource-tag[data-filter-name=${filterName}][data-filter-item=${filterItem}]`).removeClass("active"); + + // Show "No filters selected" tag, if there are no filters active + if (noFilters()) { + $(".no-tags-selected.tag").show(); + } +} + +/* Check if there are no filters */ +function noFilters() { + return ( + activeFilters.topics.length === 0 && + activeFilters.type.length === 0 && + activeFilters["payment-tiers"].length === 0 && + activeFilters.difficulty.length === 0 + ); +} + +/* Get the params out of the URL and use them. This is run when the page loads. */ +function deserializeURLParams() { + let searchParams = new window.URLSearchParams(window.location.search); + + // Work through the parameters and add them to the filter object + $.each(Object.keys(activeFilters), function(_, filterType) { + let paramFilterContent = searchParams.get(filterType); + + if (paramFilterContent !== null) { + // We use split here because we always want an array, not a string. + let paramFilterArray = paramFilterContent.split(","); + activeFilters[filterType] = paramFilterArray; + + // Update the corresponding filter UI, so it reflects the internal state. + $(paramFilterArray).each(function(_, filter) { + let checkbox = $(`.filter-checkbox[data-filter-name='${filterType}'][data-filter-item='${filter}']`); + let filterTag = $(`.filter-box-tag[data-filter-name='${filterType}'][data-filter-item='${filter}']`); + let resourceTags = $(`.resource-tag[data-filter-name='${filterType}'][data-filter-item='${filter}']`); + checkbox.prop("checked", true); + filterTag.show(); + resourceTags.addClass("active"); + }); + } + }); +} + +/* Update the URL with new parameters */ +function updateURL() { + // If there's nothing in the filters, we don't want anything in the URL. + if (noFilters()) { + window.history.replaceState(null, document.title, './'); + return; + } + + // Iterate through and get rid of empty ones + let searchParams = new URLSearchParams(activeFilters); + $.each(activeFilters, function(filterType, filters) { + if (filters.length === 0) { + searchParams.delete(filterType); + } + }); + + // Now update the URL + window.history.replaceState(null, document.title, `?${searchParams.toString()}`); +} + +/* Update the resources to match 'active_filters' */ +function updateUI() { + let resources = $('.resource-box'); + let filterTags = $('.filter-box-tag'); + + // Update the URL to match the new filters. + updateURL(); + + // If there's nothing in the filters, show everything and return. + if (noFilters()) { + resources.show(); + filterTags.hide(); + return; + } + + // Otherwise, hide everything and then filter the resources to decide what to show. + let hasMatches = false; + resources.hide(); + resources.filter(function() { + let validation = { + topics: false, + type: false, + 'payment-tiers': false, + difficulty: false + }; + let resourceBox = $(this); + + // Validate the filters + $.each(activeFilters, function(filterType, filters) { + // If the filter list is empty, this passes validation. + if (filters.length === 0) { + validation[filterType] = true; + return; + } + + // Otherwise, we need to check if one of the classes exist. + $.each(filters, function(index, filter) { + if (resourceBox.hasClass(`${filterType}-${filter}`)) { + validation[filterType] = true; + } + }); + }); + + // If validation passes, show the resource. + if (Object.values(validation).every(Boolean)) { + hasMatches = true; + return true; + } else { + return false; + } + }).show(); + + // If there are no matches, show the no matches message + if (!hasMatches) { + $(".no-resources-found").show(); + } else { + $(".no-resources-found").hide(); + } +} + +// Executed when the page has finished loading. +document.addEventListener("DOMContentLoaded", function () { + /* Check if the user has navigated to one of the old resource pages, + like pydis.com/resources/communities. In this case, we'll rewrite + the URL before we do anything else. */ + let resourceTypeInput = $("#resource-type-input").val(); + if (resourceTypeInput !== "None") { + window.history.replaceState(null, document.title, `../?type=${resourceTypeInput}`); + } + + // Update the filters on page load to reflect URL parameters. + $('.filter-box-tag').hide(); + deserializeURLParams(); + updateUI(); + + // If you collapse or uncollapse a filter group, swap the icon. + $('button.collapsible').click(function() { + let icon = $(this).find(".card-header-icon i"); + + if ($(icon).hasClass("fa-window-minimize")) { + $(icon).removeClass(["far", "fa-window-minimize"]); + $(icon).addClass(["fas", "fa-angle-down"]); + } else { + $(icon).removeClass(["fas", "fa-angle-down"]); + $(icon).addClass(["far", "fa-window-minimize"]); + } + }); + + // If you click on the div surrounding the filter checkbox, it clicks the corresponding checkbox. + $('.filter-panel').click(function() { + let checkbox = $(this).find(".filter-checkbox"); + checkbox.prop("checked", !checkbox.prop("checked")); + checkbox.change(); + }); + + // If you click on one of the tags in the filter box, it unchecks the corresponding checkbox. + $('.filter-box-tag').click(function() { + let filterItem = this.dataset.filterItem; + let filterName = this.dataset.filterName; + let checkbox = $(`.filter-checkbox[data-filter-name='${filterName}'][data-filter-item='${filterItem}']`); + + removeFilter(filterName, filterItem); + checkbox.prop("checked", false); + }); + + // If you click on one of the tags in the resource cards, it clicks the corresponding checkbox. + $('.resource-tag').click(function() { + let filterItem = this.dataset.filterItem; + let filterName = this.dataset.filterName; + let checkbox = $(`.filter-checkbox[data-filter-name='${filterName}'][data-filter-item='${filterItem}']`); + + if (!$(this).hasClass("active")) { + addFilter(filterName, filterItem); + checkbox.prop("checked", true); + } else { + removeFilter(filterName, filterItem); + checkbox.prop("checked", false); + } + }); + + // When checkboxes are toggled, trigger a filter update. + $('.filter-checkbox').change(function () { + let filterItem = this.dataset.filterItem; + let filterName = this.dataset.filterName; + + if (this.checked) { + addFilter(filterName, filterItem); + } else { + removeFilter(filterName, filterItem); + } + }); +}); diff --git a/pydis_site/templates/content/base.html b/pydis_site/templates/content/base.html index 00f4fce4..4a19a275 100644 --- a/pydis_site/templates/content/base.html +++ b/pydis_site/templates/content/base.html @@ -7,7 +7,8 @@ - + + {% endblock %} {% block content %} diff --git a/pydis_site/templates/resources/resources.html b/pydis_site/templates/resources/resources.html index c3881092..80577c2b 100644 --- a/pydis_site/templates/resources/resources.html +++ b/pydis_site/templates/resources/resources.html @@ -7,10 +7,10 @@ {% block title %}Resources{% endblock %} {% block head %} - + - - + + {% endblock %} {% block content %} -- cgit v1.2.3 From efc24acb63e4faf10644fb22b3c72aa13d792b79 Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Sun, 30 Jan 2022 20:01:27 +0100 Subject: Hide the filter tags initially. Helps prevent a flash of tags. --- pydis_site/static/css/resources/resources.css | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'pydis_site/static/css') diff --git a/pydis_site/static/css/resources/resources.css b/pydis_site/static/css/resources/resources.css index aa47be8f..ebd946d9 100644 --- a/pydis_site/static/css/resources/resources.css +++ b/pydis_site/static/css/resources/resources.css @@ -94,12 +94,17 @@ i.is-primary { /* Set default display to inline-flex, for centering. */ span.filter-box-tag { - display: inline-flex; + display: none; align-items: center; cursor: pointer; user-select: none; } +/* Make sure jQuery will use inline-flex when setting `show()` again. */ +span.filter-box-tag[style*='display: block'] { + display: inline-flex !important; +} + /* Make resource tags clickable */ .resource-tag { cursor: pointer; -- cgit v1.2.3 From bc6829b93246e2f8833b5b418d3d7bd8eadc99cf Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Sun, 30 Jan 2022 20:02:06 +0100 Subject: Make the category headers smaller on mobile. --- pydis_site/static/css/resources/resources.css | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'pydis_site/static/css') diff --git a/pydis_site/static/css/resources/resources.css b/pydis_site/static/css/resources/resources.css index ebd946d9..59f8b78e 100644 --- a/pydis_site/static/css/resources/resources.css +++ b/pydis_site/static/css/resources/resources.css @@ -187,3 +187,15 @@ span.resource-tag.active.has-background-success-light { span.resource-tag.active.has-background-info-light { animation: glow_info 4s infinite alternate; } + +/* Smaller filter category headers when on mobile */ +@media screen and (max-width: 480px) { + .filter-category-header .card-header .card-header-title { + font-size: 14px; + padding: 0; + } + .filter-panel { + padding-top: 4px; + padding-bottom: 4px; + } +} \ No newline at end of file -- cgit v1.2.3 From ca45357255f5957cf779c109fc24e83de904a195 Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Sun, 30 Jan 2022 20:25:34 +0100 Subject: Collapse category headers on load for mobile only. --- pydis_site/static/css/resources/resources.css | 8 ++++++++ pydis_site/static/js/resources/resources.js | 13 ++++++++++++- pydis_site/templates/resources/resources.html | 2 +- 3 files changed, 21 insertions(+), 2 deletions(-) (limited to 'pydis_site/static/css') diff --git a/pydis_site/static/css/resources/resources.css b/pydis_site/static/css/resources/resources.css index 59f8b78e..b24fcb5b 100644 --- a/pydis_site/static/css/resources/resources.css +++ b/pydis_site/static/css/resources/resources.css @@ -198,4 +198,12 @@ span.resource-tag.active.has-background-info-light { padding-top: 4px; padding-bottom: 4px; } +} + +/* Disable transitions */ +.no-transition { + -webkit-transition: none !important; + -moz-transition: none !important; + -o-transition: none !important; + transition: none !important; } \ No newline at end of file diff --git a/pydis_site/static/js/resources/resources.js b/pydis_site/static/js/resources/resources.js index 718e1e88..44d4db5c 100644 --- a/pydis_site/static/js/resources/resources.js +++ b/pydis_site/static/js/resources/resources.js @@ -178,7 +178,7 @@ document.addEventListener("DOMContentLoaded", function () { updateUI(); // If you collapse or uncollapse a filter group, swap the icon. - $('button.collapsible').click(function() { + $('button.collapsible').on("click", function() { let icon = $(this).find(".card-header-icon i"); if ($(icon).hasClass("fa-window-minimize")) { @@ -190,6 +190,17 @@ document.addEventListener("DOMContentLoaded", function () { } }); + // If this is a mobile device, collapse the categories to win back some screen real estate. + if (screen.width < 480) { + let categoryHeaders = $(".filter-category-header .collapsible-content"); + let icons = $('.filter-category-header button .card-header-icon i'); + categoryHeaders.addClass("no-transition"); + categoryHeaders.css("max-height", 0); + icons.removeClass(["far", "fa-window-minimize"]); + icons.addClass(["fas", "fa-angle-down"]); + categoryHeaders.removeClass("no-transition"); + } + // If you click on the div surrounding the filter checkbox, it clicks the corresponding checkbox. $('.filter-panel').click(function() { let checkbox = $(this).find(".filter-checkbox"); diff --git a/pydis_site/templates/resources/resources.html b/pydis_site/templates/resources/resources.html index 80577c2b..a7b25f5c 100644 --- a/pydis_site/templates/resources/resources.html +++ b/pydis_site/templates/resources/resources.html @@ -104,7 +104,7 @@ {% if filter_data.hidden %}
{% else %} -
+
{% endif %}
{% for filter_item in filter_data.filters %} -- cgit v1.2.3 From 8726a61b965988b30a7f28416a22d8c807177436 Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Mon, 31 Jan 2022 11:51:55 +0100 Subject: Shrink and center the duck pond 404. --- pydis_site/static/css/resources/resources.css | 10 +++++----- pydis_site/static/images/resources/duck_pond_404.jpg | Bin 0 -> 123824 bytes pydis_site/static/images/resources/duck_pond_404.png | Bin 2371374 -> 0 bytes pydis_site/templates/resources/resources.html | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 pydis_site/static/images/resources/duck_pond_404.jpg delete mode 100644 pydis_site/static/images/resources/duck_pond_404.png (limited to 'pydis_site/static/css') diff --git a/pydis_site/static/css/resources/resources.css b/pydis_site/static/css/resources/resources.css index b24fcb5b..55284605 100644 --- a/pydis_site/static/css/resources/resources.css +++ b/pydis_site/static/css/resources/resources.css @@ -64,15 +64,15 @@ display: block; /* Center the 404 div */ .no-resources-found { - display: flex; + display: none; flex-direction: column; align-items: center; + margin-top: 1em; } -/* Hide the no resources h2 by default */ -.no-resources-found { - display: none; - margin-top: 1em; +/* Make sure jQuery will use flex when setting `show()` again. */ +.no-resources-found[style*='display: block'] { + display: flex !important; } /* Disable clicking on the checkbox itself. */ diff --git a/pydis_site/static/images/resources/duck_pond_404.jpg b/pydis_site/static/images/resources/duck_pond_404.jpg new file mode 100644 index 00000000..29bcf1d6 Binary files /dev/null and b/pydis_site/static/images/resources/duck_pond_404.jpg differ diff --git a/pydis_site/static/images/resources/duck_pond_404.png b/pydis_site/static/images/resources/duck_pond_404.png deleted file mode 100644 index 3aed4d62..00000000 Binary files a/pydis_site/static/images/resources/duck_pond_404.png and /dev/null differ diff --git a/pydis_site/templates/resources/resources.html b/pydis_site/templates/resources/resources.html index dcf520f6..2fb0f543 100644 --- a/pydis_site/templates/resources/resources.html +++ b/pydis_site/templates/resources/resources.html @@ -132,7 +132,7 @@ {# Message to display when there are no hits #}

No matching resources found!

- +
-- cgit v1.2.3 From 46702b73cc8a54409da633e4492846f72bb5a338 Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Mon, 31 Jan 2022 12:07:04 +0100 Subject: Make the resource link icons a size smaller. We also add a little breathing room to the tag container, so that it doesn't encroach on the personal space of the icons. --- pydis_site/static/css/resources/resources.css | 5 +++++ pydis_site/templates/resources/resource_box.html | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'pydis_site/static/css') diff --git a/pydis_site/static/css/resources/resources.css b/pydis_site/static/css/resources/resources.css index 55284605..3b235a05 100644 --- a/pydis_site/static/css/resources/resources.css +++ b/pydis_site/static/css/resources/resources.css @@ -111,6 +111,11 @@ span.filter-box-tag[style*='display: block'] { user-select: none; } +/* Give the resource tags a bit of breathing room */ +.resource-tag-container { + padding-left: 1.5rem; +} + /* When hovering tags, brighten them a bit. */ .resource-tag:hover, .filter-box-tag:hover { diff --git a/pydis_site/templates/resources/resource_box.html b/pydis_site/templates/resources/resource_box.html index 8f634333..0ba8b0ec 100644 --- a/pydis_site/templates/resources/resource_box.html +++ b/pydis_site/templates/resources/resource_box.html @@ -16,24 +16,24 @@
{# Add primary link #} {% if 'title_url' in resource %} - + - + {% endif %} {# Add all additional icon #} {% for icon in resource.urls %} - + - + {% endfor %} {# Tags #} -
+
{% for tag in resource.tags.topics %} Date: Mon, 31 Jan 2022 12:20:40 +0100 Subject: Indent checkboxes under the headers. --- pydis_site/static/css/resources/resources.css | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'pydis_site/static/css') diff --git a/pydis_site/static/css/resources/resources.css b/pydis_site/static/css/resources/resources.css index 3b235a05..2465e9dc 100644 --- a/pydis_site/static/css/resources/resources.css +++ b/pydis_site/static/css/resources/resources.css @@ -62,6 +62,17 @@ display: block; border-radius: 0; } +/* Make the checkboxes indent under the filter headers */ +.filter-category-header .card-header .card-header-title { + padding-left: 0; +} +.filter-panel { + padding-left: 1.5rem; +} +.filter-checkbox { + margin-right: 0.25em !important; +} + /* Center the 404 div */ .no-resources-found { display: none; -- cgit v1.2.3 From 98ac8a963bc196e49b60899080b94bacc29f04e1 Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Mon, 31 Jan 2022 16:05:13 +0100 Subject: Added margins and max-width to filtering column. --- pydis_site/static/css/resources/resources.css | 20 ++++++++++++++------ pydis_site/templates/resources/resources.html | 4 ++-- 2 files changed, 16 insertions(+), 8 deletions(-) (limited to 'pydis_site/static/css') diff --git a/pydis_site/static/css/resources/resources.css b/pydis_site/static/css/resources/resources.css index 2465e9dc..26ddc14e 100644 --- a/pydis_site/static/css/resources/resources.css +++ b/pydis_site/static/css/resources/resources.css @@ -163,6 +163,14 @@ span.resource-tag.active { outline-style: solid; } +/* Disable transitions */ +.no-transition { + -webkit-transition: none !important; + -moz-transition: none !important; + -o-transition: none !important; + transition: none !important; +} + /* Make filter tags sparkle when selected! */ @keyframes glow_success { from { box-shadow: 0 0 2px 2px #aef4af; } @@ -216,10 +224,10 @@ span.resource-tag.active.has-background-info-light { } } -/* Disable transitions */ -.no-transition { - -webkit-transition: none !important; - -moz-transition: none !important; - -o-transition: none !important; - transition: none !important; +/* Constrain the width of the filterbox */ +@media screen and (min-width: 769px) { + .filtering-column { + max-width: 25rem; + min-width: 18rem; + } } \ No newline at end of file diff --git a/pydis_site/templates/resources/resources.html b/pydis_site/templates/resources/resources.html index 2fb0f543..13bba1f2 100644 --- a/pydis_site/templates/resources/resources.html +++ b/pydis_site/templates/resources/resources.html @@ -17,9 +17,9 @@ {% include "base/navbar.html" %}
-
+
{# Filtering toolbox #} -
+
{% endblock %} - - -- cgit v1.2.3 From 24edd0ada26af34e946965d5692b6a35b7622ef9 Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Mon, 31 Jan 2022 22:16:20 +0100 Subject: Add a button for removing all active filters. --- pydis_site/static/css/resources/resources.css | 21 ++++- pydis_site/static/js/resources/resources.js | 67 +++++++++------ pydis_site/templates/resources/resources.html | 118 ++++++++++++++------------ 3 files changed, 123 insertions(+), 83 deletions(-) (limited to 'pydis_site/static/css') diff --git a/pydis_site/static/css/resources/resources.css b/pydis_site/static/css/resources/resources.css index 16226936..2fb3a9b5 100644 --- a/pydis_site/static/css/resources/resources.css +++ b/pydis_site/static/css/resources/resources.css @@ -97,12 +97,29 @@ i.is-primary { color: #7289da; } -/* A little space around the filter card, please! */ +/* A little space above the filter card, please! */ .filter-tags { padding-bottom: .5em; - padding-right: .5em; } +/* Style the close all filters button */ +.close-filters-button { + margin-left: auto; + display:none; +} +.close-filters-button a { + height: fit-content; + width: fit-content; + margin-right: 6px; +} +.close-filters-button a i { + color: #939bb3; +} +.close-filters-button a i:hover { + filter: brightness(115%); +} + + /* Set default display to inline-flex, for centering. */ span.filter-box-tag { display: none; diff --git a/pydis_site/static/js/resources/resources.js b/pydis_site/static/js/resources/resources.js index 0e951c38..8627a359 100644 --- a/pydis_site/static/js/resources/resources.js +++ b/pydis_site/static/js/resources/resources.js @@ -8,42 +8,33 @@ var activeFilters = { difficulty: [] }; +/* Add a filter, and update the UI */ function addFilter(filterName, filterItem) { - // Push the filter into the stack var filterIndex = activeFilters[filterName].indexOf(filterItem); if (filterIndex === -1) { activeFilters[filterName].push(filterItem); } updateUI(); +} - // Show a corresponding filter box tag - $(`.filter-box-tag[data-filter-name=${filterName}][data-filter-item=${filterItem}]`).show(); - - // Make corresponding resource tags active - $(`.resource-tag[data-filter-name=${filterName}][data-filter-item=${filterItem}]`).addClass("active"); - - // Hide the "No filters selected" tag. - $(".no-tags-selected.tag").hide(); +/* Remove all filters, and update the UI */ +function removeAllFilters() { + activeFilters = { + topics: [], + type: [], + "payment-tiers": [], + difficulty: [] + }; + updateUI(); } +/* Remove a filter, and update the UI */ function removeFilter(filterName, filterItem) { - // Remove the filter from the stack var filterIndex = activeFilters[filterName].indexOf(filterItem); if (filterIndex !== -1) { activeFilters[filterName].splice(filterIndex, 1); } updateUI(); - - // Hide the corresponding filter box tag - $(`.filter-box-tag[data-filter-name=${filterName}][data-filter-item=${filterItem}]`).hide(); - - // Make corresponding resource tags inactive - $(`.resource-tag[data-filter-name=${filterName}][data-filter-item=${filterItem}]`).removeClass("active"); - - // Show "No filters selected" tag, if there are no filters active - if (noFilters()) { - $(".no-tags-selected.tag").show(); - } } /* Check if there are no filters */ @@ -76,7 +67,7 @@ function deserializeURLParams() { window.location.href = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"; } else if (String(filter) === "sneakers" && filterType === "topics") { window.location.href = "https://www.youtube.com/watch?v=NNZscmNE9QI"; - } else if (validFilters[filterType].includes(String(filter))) { + } else if (validFilters.hasOwnProperty(filterType) && validFilters[filterType].includes(String(filter))) { let checkbox = $(`.filter-checkbox[data-filter-name='${filterType}'][data-filter-item='${filter}']`); let filterTag = $(`.filter-box-tag[data-filter-name='${filterType}'][data-filter-item='${filter}']`); let resourceTags = $(`.resource-tag[data-filter-name='${filterType}'][data-filter-item='${filter}']`); @@ -91,9 +82,10 @@ function deserializeURLParams() { // Ditch all the params from the URL, and recalculate the URL params updateURL(); - // If we've added a filter, hide the no filters tag. + // If we've added a filter, hide stuff if (filterAdded) { $(".no-tags-selected.tag").hide(); + $(".close-filters-button").show(); } } }); @@ -123,15 +115,36 @@ function updateURL() { function updateUI() { let resources = $('.resource-box'); let filterTags = $('.filter-box-tag'); + let noTagsSelected = $(".no-tags-selected.tag"); + let closeFiltersButton = $(".close-filters-button"); // Update the URL to match the new filters. updateURL(); - // If there's nothing in the filters, show everything and return. + // If there's nothing in the filters, we can return early. if (noFilters()) { resources.show(); filterTags.hide(); + noTagsSelected.show(); + closeFiltersButton.hide(); + $(`.filter-checkbox:checked`).prop("checked", false) return; + } else { + $.each(activeFilters, function(filterType, filters) { + $.each(filters, function(index, filter) { + // Show a corresponding filter box tag + $(`.filter-box-tag[data-filter-name=${filterType}][data-filter-item=${filter}]`).show(); + + // Make corresponding resource tags active + $(`.resource-tag[data-filter-name=${filterType}][data-filter-item=${filter}]`).addClass("active"); + + // Hide the "No filters selected" tag. + noTagsSelected.hide(); + + // Show the close filters button + closeFiltersButton.show(); + }); + }); } // Otherwise, hide everything and then filter the resources to decide what to show. @@ -147,7 +160,6 @@ function updateUI() { let resourceBox = $(this); // Validate the filters - $.each(activeFilters, function(filterType, filters) { // If the filter list is empty, this passes validation. if (filters.length === 0) { @@ -256,6 +268,11 @@ document.addEventListener("DOMContentLoaded", function () { } }); + // When you click the little gray x, remove all filters. + $(".close-filters-button").on("click", function() { + removeAllFilters(); + }); + // When checkboxes are toggled, trigger a filter update. $('.filter-checkbox').on("change", function (event) { let filterItem = this.dataset.filterItem; diff --git a/pydis_site/templates/resources/resources.html b/pydis_site/templates/resources/resources.html index 4b7e9040..cebaace2 100644 --- a/pydis_site/templates/resources/resources.html +++ b/pydis_site/templates/resources/resources.html @@ -31,64 +31,70 @@ {# Filter box tags #}
-
- {# A little x in the top right, visible only when filters are active, which removes all filters. #} - - - {# A filter tag for when there are no filters active #} - - - No filters selected - +
+
+ {# A filter tag for when there are no filters active #} + + + No filters selected + - {% for filter_name, filter_data in filters.items %} - {% for filter_item in filter_data.filters %} - {% if filter_name == "Difficulty" %} - - - {{ filter_item|title }} - - - {% endif %} - {% if filter_name == "Type" %} - - - {{ filter_item|title }} - - - {% endif %} - {% if filter_name == "Payment tiers" %} - - - {{ filter_item|title }} - - - {% endif %} - {% if filter_name == "Topics" %} - - - {{ filter_item|title }} - - - {% endif %} + {% for filter_name, filter_data in filters.items %} + {% for filter_item in filter_data.filters %} + {% if filter_name == "Difficulty" %} + + + {{ filter_item|title }} + + + {% endif %} + {% if filter_name == "Type" %} + + + {{ filter_item|title }} + + + {% endif %} + {% if filter_name == "Payment tiers" %} + + + {{ filter_item|title }} + + + {% endif %} + {% if filter_name == "Topics" %} + + + {{ filter_item|title }} + + + {% endif %} + {% endfor %} {% endfor %} - {% endfor %} +
+
+ {# A little x in the top right, visible only when filters are active, which removes all filters. #} + + + + +
-- cgit v1.2.3 From 3c92f66890a67a19ba082acd50ebcd2df311f305 Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Tue, 1 Feb 2022 01:21:21 +0100 Subject: When hovering titles, make them light, not black. --- pydis_site/static/css/resources/resources.css | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'pydis_site/static/css') diff --git a/pydis_site/static/css/resources/resources.css b/pydis_site/static/css/resources/resources.css index 2fb3a9b5..b8456e38 100644 --- a/pydis_site/static/css/resources/resources.css +++ b/pydis_site/static/css/resources/resources.css @@ -119,6 +119,12 @@ i.is-primary { filter: brightness(115%); } +/* When hovering title anchors, just make the color a lighter primary, not black. */ +.resource-box a:hover { + filter: brightness(120%); + color: #7289DA; +} + /* Set default display to inline-flex, for centering. */ span.filter-box-tag { -- cgit v1.2.3 From d31340f8abeabc5df1c778d7d8eae4d0806fad0e Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Tue, 1 Feb 2022 02:13:34 +0100 Subject: Fix bug where transition wouldn't work on first collapse. --- pydis_site/static/css/collapsibles.css | 6 +++++- pydis_site/static/js/collapsibles.js | 6 +----- pydis_site/static/js/resources/resources.js | 7 ++++--- pydis_site/templates/resources/resources.html | 4 ++-- 4 files changed, 12 insertions(+), 11 deletions(-) (limited to 'pydis_site/static/css') diff --git a/pydis_site/static/css/collapsibles.css b/pydis_site/static/css/collapsibles.css index 8fdd1f12..d35e77ea 100644 --- a/pydis_site/static/css/collapsibles.css +++ b/pydis_site/static/css/collapsibles.css @@ -6,7 +6,11 @@ } .collapsible-content { + max-height: 40em; + transition: max-height 0.3s ease-out; +} + +.collapsible-content.collapsed { overflow: hidden; max-height: 0; - transition: max-height 0.2s ease-out; } diff --git a/pydis_site/static/js/collapsibles.js b/pydis_site/static/js/collapsibles.js index 366a033c..d12d9f86 100644 --- a/pydis_site/static/js/collapsibles.js +++ b/pydis_site/static/js/collapsibles.js @@ -3,11 +3,7 @@ document.addEventListener("DOMContentLoaded", () => { for (const header of headers) { header.addEventListener("click", () => { var content = header.nextElementSibling; - if (content.style.maxHeight){ - content.style.maxHeight = null; - } else { - content.style.maxHeight = content.scrollHeight + "px"; - } + content.classList.toggle('collapsed'); }); } }); diff --git a/pydis_site/static/js/resources/resources.js b/pydis_site/static/js/resources/resources.js index bffb5e91..00bc6ad8 100644 --- a/pydis_site/static/js/resources/resources.js +++ b/pydis_site/static/js/resources/resources.js @@ -234,11 +234,12 @@ document.addEventListener("DOMContentLoaded", function () { if (screen.width < 480) { let categoryHeaders = $(".filter-category-header .collapsible-content"); let icons = $('.filter-category-header button .card-header-icon i'); - categoryHeaders.addClass("no-transition"); - categoryHeaders.css("max-height", ""); + categoryHeaders.addClass("no-transition collapsed"); icons.removeClass(["far", "fa-window-minimize"]); icons.addClass(["fas", "fa-angle-down"]); - categoryHeaders.removeClass("no-transition"); + + // Wait 10ms before removing this class, or else the transition will animate due to a race condition. + setTimeout(() => { categoryHeaders.removeClass("no-transition"); }, 10); } // If you click on the div surrounding the filter checkbox, it clicks the corresponding checkbox. diff --git a/pydis_site/templates/resources/resources.html b/pydis_site/templates/resources/resources.html index cebaace2..c221c8a3 100644 --- a/pydis_site/templates/resources/resources.html +++ b/pydis_site/templates/resources/resources.html @@ -116,9 +116,9 @@ {# Checkboxes #} {% if filter_data.hidden %} -
+