feat: create posts instead of cards

This commit is contained in:
ktyl 2024-07-11 21:19:51 +01:00
parent ef58ed4af3
commit 29b975a60c
3 changed files with 86 additions and 52 deletions

View File

@ -4,19 +4,19 @@
</head> </head>
<body> <body>
<!-- cards are added by JavaScript so it starts empty --> <!-- posts are added by JavaScript so container starts empty -->
<div id="card-container"></div> <div id="post-container"></div>
<!-- loader displays an animation before adding the next batch of cards --> <!-- loader displays an animation before adding the next batch of posts -->
<div id="loader"> <div id="loader">
<div class="skeleton-card"></div> <div class="skeleton-post"></div>
</div> </div>
<!-- card actions shows the card count and card total (we probably do not need this) --> <!-- post actions shows the post count and post total (we probably do not need this) -->
<div id="card-actions"> <div id="post-actions">
<span>Showing <span>Showing
<span id="card-count"></span> of <span id="post-count"></span> of
<span id="card-total"></span> cards <span id="post-total"></span> cards
</span> </span>
</div> </div>

87
main.js
View File

@ -1,20 +1,20 @@
// first, let's get all the elements we'll need from our DOM // first, let's get all the elements we'll need from our DOM
const cardContainer = document.getElementById("card-container"); const postContainer = document.getElementById("post-container");
const cardCountElem = document.getElementById("card-count"); const postCountElem = document.getElementById("post-count");
const cardTotalElem = document.getElementById("card-total"); const postTotalElem = document.getElementById("post-total");
const loader = document.getElementById("loader"); const loader = document.getElementById("loader");
// we'll need a value for the max numaer of cards to be added to the page // we'll need a value for the max numaer of posts to be added to the page
const cardLimit = 99; const postLimit = 99;
// then we'll define a variable for how many cards we want to increase the // then we'll define a variable for how many posts we want to increase the
// page by // page by
const cardIncrease = 9; const postIncrease = 9;
// how many times can we increase the content until we reach the max limit? // how many times can we increase the content until we reach the max limit?
const pageCount = Math.ceil(cardLimit / cardIncrease); const pageCount = Math.ceil(postLimit / postIncrease);
// and define a value to determine which page we're on // and define a value to determine which page we're on
let currentPage = 1; let currentPage = 1;
cardTotalElem.innerHTML = cardLimit; postTotalElem.innerHTML = postLimit;
function getRandomColor() { function getRandomColor() {
@ -23,27 +23,67 @@ function getRandomColor() {
} }
function createCard(idx) { function getUsername() {
const card = document.createElement("div"); const usernames = [
card.className = "card"; "xXPu55y5l4y3r69Xx",
card.innerHTML = idx; "Keef Farmer",
card.style.backgroundColor = getRandomColor(); "Alan"
cardContainer.appendChild(card); ];
const r = Math.floor(Math.random() * usernames.length);
return usernames[r];
} }
function addCards(pageIdx) { function getContent() {
return "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
}
class Post {
constructor() {
this.username = getUsername();
this.content = getContent();
}
getElement() {
const postElem = document.createElement("div");
postElem.className = "post";
postElem.style.backgroundColor = getRandomColor();
// add a header to the post
const headerElem = document.createElement("h1");
headerElem.innerHTML = this.username;
postElem.appendChild(headerElem);
// TODO: add content to the post
const contentElem = document.createElement("p");
contentElem.innerHTML = this.content;
postElem.appendChild(contentElem);
return postElem;
}
}
function createPost() {
const post = new Post();
postContainer.appendChild(post.getElement());
}
function addPosts(pageIdx) {
currentPage = pageIdx; currentPage = pageIdx;
const startRange = (pageIdx - 1) * cardIncrease; const startRange = (pageIdx - 1) * postIncrease;
const endRange = currentPage == pageCount const endRange = currentPage == pageCount
? cardLimit ? postLimit
: pageIdx * cardIncrease; : pageIdx * postIncrease;
cardCountElem.innerHTML = endRange; postCountElem.innerHTML = endRange;
for (let i = startRange + 1; i <= endRange; i++) { for (let i = startRange + 1; i <= endRange; i++) {
createCard(i); createPost();
} }
} }
@ -53,7 +93,7 @@ function handleInfiniteScroll() {
const endOfPage = window.innerHeight + window.pageYOffset >= document.body.offsetHeight; const endOfPage = window.innerHeight + window.pageYOffset >= document.body.offsetHeight;
if (endOfPage) { if (endOfPage) {
addCards(currentPage + 1); addPosts(currentPage + 1);
} }
if (currentPage === pageCount) { if (currentPage === pageCount) {
@ -63,6 +103,7 @@ function handleInfiniteScroll() {
} }
// limit how often we try to load new posts to maintain browser performance
var throttleTimer; var throttleTimer;
function throttle(callback, time) { function throttle(callback, time) {
if (throttleTimer) return; if (throttleTimer) return;
@ -81,7 +122,7 @@ function removeInfiniteScroll() {
window.removeEventListener("scroll", handleInfiniteScroll); window.removeEventListener("scroll", handleInfiniteScroll);
} }
addCards(currentPage); addPosts(currentPage);
window.addEventListener("scroll", handleInfiniteScroll); window.addEventListener("scroll", handleInfiniteScroll);
// TODO: define the limit of the content to be loaded on the page // TODO: define the limit of the content to be loaded on the page

View File

@ -1,4 +1,4 @@
#card-container { #post-container {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: center; justify-content: center;
@ -8,27 +8,28 @@
@media only screen and (min-width: 768px) { @media only screen and (min-width: 768px) {
/* For bigger than phones */ /* For bigger than phones */
#card-container { #post-container {
max-width: 600px !important; max-width: 600px;
}
#loader {
max-width: 600px;
} }
} }
.card { .post {
height: 55vh; height: 55vh;
width: calc(100% - 16px); width: calc(100% - 16px);
margin: 8px; margin: 8px;
border-radius: 3px; border-radius: 3px;
transition: all 200ms ease-in-out; transition: all 200ms ease-in-out;
display: flex;
align-items: center;
justify-content: center;
} }
.card:hover { .post:hover {
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2); box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
} }
.card-actions { .post-actions {
margin: 8px; margin: 8px;
padding: 16px 0; padding: 16px 0;
display: flex; display: flex;
@ -38,9 +39,11 @@
#loader { #loader {
display: flex; display: flex;
justify-content: center;
margin-inline: auto;
} }
.skeleton-card { .skeleton-post {
height: 55vh; height: 55vh;
width: calc(100% - 16px); width: calc(100% - 16px);
margin: 8px; margin: 8px;
@ -50,7 +53,7 @@
background-color: #eaeaea; background-color: #eaeaea;
} }
.skeleton-card::after { .skeleton-post::after {
content: ""; content: "";
position: absolute; position: absolute;
top: 0; top: 0;
@ -59,14 +62,4 @@
left: 0; left: 0;
transform: translateX(-100%); transform: translateX(-100%);
background-image: linear-gradient(90deg, rgba(255, 255, 255, 0) 0, rgba(255, 255, 255, 0.2) 20%, rgba(255, 255, 255, 0.5) 60%, rgba(255, 255, 255, 0)); background-image: linear-gradient(90deg, rgba(255, 255, 255, 0) 0, rgba(255, 255, 255, 0.2) 20%, rgba(255, 255, 255, 0.5) 60%, rgba(255, 255, 255, 0));
animation: load is infinite;
}
@keyframes load {
100% {
transform: translateX(100%);
}
}
@media screen and (prefers-reduced-motion: reduce) {
} }