aboutsummaryrefslogtreecommitdiffstats
path: root/pydis_site/static
diff options
context:
space:
mode:
Diffstat (limited to 'pydis_site/static')
-rw-r--r--pydis_site/static/css/resources/resources.css91
-rw-r--r--pydis_site/static/js/resources.js123
2 files changed, 181 insertions, 33 deletions
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);
}
});
});