Compare commits

...

2 Commits

Author SHA1 Message Date
ktyl 0108c871b8 wip: add icon cluster 2024-08-04 20:17:19 +01:00
ktyl c6bd7d80d6 feat: use reply endpoint 2024-08-04 19:33:00 +01:00
6 changed files with 117 additions and 18 deletions

View File

@ -1,2 +1,4 @@
infinite scrolling
https://webdesign.tutsplus.com/how-to-implement-infinite-scrolling-with-javascript--cms-37055t
Icons from https://fontawesome.com/

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M0 48C0 21.5 21.5 0 48 0l0 48 0 393.4 130.1-92.9c8.3-6 19.6-6 27.9 0L336 441.4 336 48 48 48 48 0 336 0c26.5 0 48 21.5 48 48l0 440c0 9-5 17.2-13 21.3s-17.6 3.4-24.9-1.8L192 397.5 37.9 507.5c-7.3 5.2-16.9 5.9-24.9 1.8S0 497 0 488L0 48z"/></svg>

After

Width:  |  Height:  |  Size: 464 B

1
icon/retweet-solid.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M272 416c17.7 0 32-14.3 32-32s-14.3-32-32-32l-112 0c-17.7 0-32-14.3-32-32l0-128 32 0c12.9 0 24.6-7.8 29.6-19.8s2.2-25.7-6.9-34.9l-64-64c-12.5-12.5-32.8-12.5-45.3 0l-64 64c-9.2 9.2-11.9 22.9-6.9 34.9s16.6 19.8 29.6 19.8l32 0 0 128c0 53 43 96 96 96l112 0zM304 96c-17.7 0-32 14.3-32 32s14.3 32 32 32l112 0c17.7 0 32 14.3 32 32l0 128-32 0c-12.9 0-24.6 7.8-29.6 19.8s-2.2 25.7 6.9 34.9l64 64c12.5 12.5 32.8 12.5 45.3 0l64-64c9.2-9.2 11.9-22.9 6.9-34.9s-16.6-19.8-29.6-19.8l-32 0 0-128c0-53-43-96-96-96L304 96z"/></svg>

After

Width:  |  Height:  |  Size: 735 B

1
icon/star-regular.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M287.9 0c9.2 0 17.6 5.2 21.6 13.5l68.6 141.3 153.2 22.6c9 1.3 16.5 7.6 19.3 16.3s.5 18.1-5.9 24.5L433.6 328.4l26.2 155.6c1.5 9-2.2 18.1-9.7 23.5s-17.3 6-25.3 1.7l-137-73.2L151 509.1c-8.1 4.3-17.9 3.7-25.3-1.7s-11.2-14.5-9.7-23.5l26.2-155.6L31.1 218.2c-6.5-6.4-8.7-15.9-5.9-24.5s10.3-14.9 19.3-16.3l153.2-22.6L266.3 13.5C270.4 5.2 278.7 0 287.9 0zm0 79L235.4 187.2c-3.5 7.1-10.2 12.1-18.1 13.3L99 217.9 184.9 303c5.5 5.5 8.1 13.3 6.8 21L171.4 443.7l105.2-56.2c7.1-3.8 15.6-3.8 22.6 0l105.2 56.2L384.2 324.1c-1.3-7.7 1.2-15.5 6.8-21l85.9-85.1L358.6 200.5c-7.8-1.2-14.6-6.1-18.1-13.3L287.9 79z"/></svg>

After

Width:  |  Height:  |  Size: 821 B

84
main.js
View File

@ -60,6 +60,8 @@ class Post {
this.replyTo = data.replyTo;
this.parentPost = null;
this.stars = 420;
this.replies = [];
}
@ -113,6 +115,44 @@ class Post {
getContentElement() {
const elem = document.createElement("p");
elem.innerHTML = this.content;
return elem;
}
getIconElement(svg, right) {
const elem = document.createElement("div");
elem.className = "icon";
right *= 94;
elem.style.right = `${right}px`;
const imgElem = document.createElement("img");
imgElem.className = "icon-img";
imgElem.setAttribute("src", svg);
elem.appendChild(imgElem);
const countElem = document.createElement("span");
// TODO: make an icon class to store count OR i guess just parse it out of the DOM
countElem.className = "icon-count";
countElem.innerHTML = "42069";
elem.appendChild(countElem);
return elem;
}
getFooterElement() {
const elem = document.createElement("div");
elem.className = "post-footer";
const starIconElem = this.getIconElement("icon/star-regular.svg", 0);
elem.appendChild(starIconElem);
const repostElem = this.getIconElement("icon/retweet-solid.svg", 1)
elem.appendChild(repostElem);
const bookmarkElem = this.getIconElement("icon/bookmark-regular.svg", 2);
elem.appendChild(bookmarkElem);
return elem;
}
@ -138,6 +178,7 @@ class Post {
elem.className = classes.join(" ");
elem.appendChild(this.getHeaderElement());
elem.appendChild(this.getContentElement());
elem.appendChild(this.getFooterElement());
elem.appendChild(this.getReplyButton());
for (let i = 0; i < this.replies.length; i++) {
@ -258,40 +299,55 @@ function getCurrentUser() {
};
}
function writePost(postCallback) {
const request = {
function getPostRequest(body) {
return {
method: "POST",
mode: "cors",
body: JSON.stringify(getCurrentUser()),
body: JSON.stringify(body),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
};
}
function writePost() {
if (localMode) {
const post = new Post({
id: "1234",
associatedUser: getCurrentUser().user,
body: "local mode post (local mode post)"
});
postCallback(post);
} else {
fetch("https://api.wayfarer.games/singularity/generate-posts.php", request)
blockContainer.insertBefore(post.getElement(), getTopPost());
return;
}
fetch("https://api.wayfarer.games/singularity/generate-posts.php", getPostRequest(getCurrentUser()))
.then(response => response.json())
.then(makePostFromJson)
.then(postCallback);
}
}
function writeNewPost() {
writePost(post => blockContainer.insertBefore(post.getElement(), getTopPost()));
.then(post => blockContainer.insertBefore(post.getElement(), getTopPost()));
}
function writeReply(post) {
// find the correct element
const elem = document.getElementById(post.id);
const user = getCurrentUser();
writePost(reply => {
if (localMode) {
console.error("TODO: implement local replies");
return;
}
const replyBody = {
postId: post.id,
interests: user.interests,
user: user.user,
posting_style: user.posting_style
};
const request = getPostRequest(replyBody);
fetch("https://api.wayfarer.games/singularity/generate-reply.php", getPostRequest(replyBody))
.then(response => response.json())
.then(makePostFromJson)
.then(reply => {
post.addReply(reply);
elem.append(reply.getElement());
});
@ -300,7 +356,7 @@ function writeReply(post) {
function addWritePostBlock() {
const blockElem = document.createElement("div");
blockElem.addEventListener("click", writeNewPost);
blockElem.addEventListener("click", writePost);
blockElem.className = "block write-post";
const spanElem = document.createElement("h2");

View File

@ -2,6 +2,10 @@
--header-height: 64px;
--blue-gray: #374955;
--sky-blue: #86b1cc;
/* use filter: instead of color: to color SVGs
* https://isotropic.co/tool/hex-color-to-css-filter/ */
--blue-gray-filter: invert(27%) sepia(20%) saturate(575%) hue-rotate(161deg) brightness(93%) contrast(93%);
--sky-blue-filter: invert(73%) sepia(16%) saturate(657%) hue-rotate(160deg) brightness(90%) contrast(91%);
--comment-column-width: 3px;
}
@ -154,6 +158,40 @@ body {
justify-content: left;
}
.post-footer {
position: relative;
}
.icon {
color: var(--sky-blue);
height: 32px;
width: 100px;
position: absolute;
top: 16px;
}
.icon-img {
filter: var(--blue-gray-filter);
height: 32px;
width: 32px;
display: inline-block;
}
.icon-img.active {
filter: var(--sky-blue-filter)
}
.icon-count {
color: var(--blue-gray);
height: 100%;
display: flex;
align-items: center;
position: absolute;
top: 0;
left: 32px;
margin-left: 4px;
}
.write-post {
cursor: pointer;
color: var(--blue-gray);