Skip to content

Commit aa18042

Browse files
committed
Bring in conferences, tweak some icons and styles, create separate clickable card and renderer
1 parent 9bacc2a commit aa18042

11 files changed

Lines changed: 1303 additions & 24232 deletions

File tree

include/pregen-news.inc

Lines changed: 0 additions & 23572 deletions
This file was deleted.
-103 Bytes
Loading

public/images/logos/elephpant.svg

Lines changed: 614 additions & 0 deletions
Loading

public/index.php

Lines changed: 156 additions & 303 deletions
Large diffs are not rendered by default.

public/js/common.js

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -879,3 +879,87 @@ function applyTheme(theme) {
879879
}
880880

881881
applyTheme(savedTheme)
882+
883+
const GstCardHelpers = {
884+
shuffleImmutableArray: (array) => {
885+
const newArray = [...array];
886+
for (let i = newArray.length - 1; i > 0; i--) {
887+
const j = Math.floor(Math.random() * (i + 1));
888+
[newArray[i], newArray[j]] = [newArray[j], newArray[i]];
889+
}
890+
return newArray;
891+
},
892+
893+
shuffleDOMChildrenWithLimit: (parent, limit) => {
894+
const children = Array.from(parent.children);
895+
const replacements = GstCardHelpers.shuffleImmutableArray(children).slice(0, limit);
896+
897+
while (parent.children.length) {
898+
parent.removeChild(parent.children[0]);
899+
}
900+
901+
replacements.forEach(n => parent.appendChild(n));
902+
},
903+
904+
dynamicAlignment: (parent, targetWidth) => {
905+
parent.style.display = 'flex';
906+
parent.style.flexWrap = 'wrap';
907+
parent.style.justifyContent = 'center';
908+
909+
let resizeTimer;
910+
911+
const resizeObserver = new ResizeObserver((entries) => {
912+
// Instantly apply the class that kills transitions on children
913+
// the transition is there for the hover effects but it makes it ugly when resizing
914+
parent.classList.add('gst-no-transition');
915+
916+
// Clear previous timeout and set a new one to restore transitions
917+
// 100ms after the resize completely stops.
918+
clearTimeout(resizeTimer);
919+
resizeTimer = setTimeout(() => {
920+
parent.classList.remove('gst-no-transition');
921+
}, 100);
922+
923+
for (const entry of entries) {
924+
const containerWidth = entry.contentRect.width;
925+
const children = Array.from(parent.children);
926+
const itemCount = children.length;
927+
928+
// Prevent dividing by zero or calculating for empty containers
929+
if (itemCount === 0 || containerWidth === 0) continue;
930+
931+
const computedStyle = window.getComputedStyle(parent);
932+
const columnGap = parseFloat(computedStyle.columnGap) || 0;
933+
934+
// Calculate the max number of items that can theoretically fit in one row
935+
let columnsPerRow = Math.floor((containerWidth + columnGap) / (targetWidth + columnGap));
936+
if (columnsPerRow < 1) columnsPerRow = 1;
937+
938+
let itemWidth;
939+
940+
if (itemCount >= columnsPerRow) {
941+
// We have enough items to completely fill at least one row.
942+
// Calculate exact width needed to stretch across the full container.
943+
const exactWidth = (containerWidth - (columnsPerRow - 1) * columnGap) / columnsPerRow;
944+
945+
// Subtract 0.5px margin of error to guarantee that browser rounding
946+
// engines never accidentally push the final item onto the next row.
947+
itemWidth = exactWidth - 0.5;
948+
} else {
949+
// We DO NOT have enough items to completely fill a single row.
950+
// Constrain them to the targetWidth, clamping it if the container is tiny.
951+
itemWidth = Math.min(targetWidth, containerWidth);
952+
}
953+
954+
// Apply synchronously so it paints in the same frame
955+
children.forEach((child) => {
956+
child.style.boxSizing = 'border-box';
957+
child.style.width = `${itemWidth}px`;
958+
child.style.flex = `0 0 ${itemWidth}px`;
959+
});
960+
}
961+
});
962+
963+
resizeObserver.observe(parent);
964+
}
965+
};

0 commit comments

Comments
 (0)