From c3291fd93051e22fa69cb99fc07e81cd29c9dcbd Mon Sep 17 00:00:00 2001 From: Flummi Date: Tue, 7 May 2019 20:23:19 +0000 Subject: [PATCH] Frontend lol --- public/css/f0ck.css | 187 +++++++++++++++++++++++++++++--------------- public/js/f0ck.js | 151 +++++++++++++++++++++++++++++++++++ public/js/rt.js | 29 +++++++ public/js/test.js | 0 4 files changed, 304 insertions(+), 63 deletions(-) create mode 100644 public/js/rt.js create mode 100644 public/js/test.js diff --git a/public/css/f0ck.css b/public/css/f0ck.css index 8e1b370..9771402 100644 --- a/public/css/f0ck.css +++ b/public/css/f0ck.css @@ -26,7 +26,11 @@ body { background-color: var(--bg-color); color: var(--font-color); - /*overflow: hidden;*/ + + overflow: hidden; + height: 100%; + margin: 0; + padding: 0; } /* End of Body */ @@ -53,70 +57,9 @@ button { border-radius: 0px; vertical-align: bottom !important; } - -img.logo { - height: 48px; -} + /* END OF NAV */ -/* f0ck Grid! */ -.f0ckgrid { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(128px, 1fr)); - grid-gap: 20px; - align-items: stretch; -} - -.f0ckgrid img { - box-shadow: 2px 2px 6px 0px rgb(0, 0, 0); - max-width: 100%; -} -/* End of f0ck Grid! */ - -/* Image Thumbs */ -a img.thumb { - border: 2px solid black; - transition: .1s ease-out; -} - -img.thumb:hover { - box-shadow: 0px 0px 0px 2px #dac8d2; - border-radius: 5px; - transition: .1s ease-in; -} -/* End of Image Thumbs */ - -/* List Styling -ul.f0ck-links { - list-style: none; - display: flex; - justify-content: center; - align-items: center; - flex-wrap: wrap; -} - -li.post { - width: 128px; - height: 128px; - margin-top: 5px; - line-height: 128px; - float: left; - margin: 5px; - transition: .1s ease-out; -} - -li.post:hover { - box-shadow: 0px 0px 0px 2px #dac8d2; - border-radius: 5px; - transition: .1s ease-in; -} - -li.post:hover img { -border-radius: 5px; -opacity: 0.8; -} -End of List Styling */ - /* MISC */ ::-webkit-scrollbar { width: 12px; @@ -131,3 +74,121 @@ End of List Styling */ border-radius: 10px; -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5); } + +/* Flummikram lol */ +div.pscroll { + opacity: 0.7; + position: fixed; + display: inline-block; + height: 64px; + width: 64px; + left: 50%; + cursor: pointer; + margin-left: -36px; + z-index: 999; +} +div.pscroll:hover { + opacity: 0.9; +} +div#up { + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAANlBMVEUiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIjIyP///8iIiLm5uY3NzdKSkpAQEAqKipZf6aEAAAACnRSTlOxIfAAKvPn6quuQpaxIgAAAMZJREFUeF7t17uOwjAYROHjOMCuL0l4/5ddbQU0M4p/RIE8/flkyY1NTr/XNrjrT8qsSwtsWaGFBpcYcKEF9xFgAhMo9xIBytFrP8owUPb6v10JmN4K6N4L6N4L6N4L6N4L6N4L6N4L6N4L6N4L6N4L6N4L6N4L6N4L6N4L6N4L6N4L6N4L6N4L6N4L6N4L6N4LiN4LD2Cv53c8AaUPAL08AXVk9zeeoG3nhb69XuP5fdkLZQITmED840kMIP75zonbaH4j5T8NALtW477R3QAAAABJRU5ErkJggg=='); + top: 5.8em; +} +div#down { + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAANlBMVEUiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIjIyMiIiLm5uY3NzcqKipAQED///9KSkpHtWFIAAAACnRSTlMqACGx8/Cu6uerGsmyTAAAAM9JREFUeF7t1zkOwzAMBVEt3kLK2/0vm3KQivhWigTQ7+dBpZhyeW3+cNtSckqzd2xOafGu1TT1AVPyzv0YMIABDMD0fQB7u9S1HcCNXhAM4CAQZl98gZ8PgNsB3G69NwAEqQdAUHoABKUHQNB6AAStB0DQegAErQdA0HoABK0HQNB6AAShBwgE+gBACHuAWKCPAIS4B4gEegFAoHcFQKBXAAR6BUCgVwAEehlAoNcBt7Nd7TTXAYjD/uKDMYAB9B+etQ+o/cd3Lsv6NF9ryW9/v8EFMSsbFgAAAABJRU5ErkJggg=='); + bottom: 5em; +} +footer { + position: fixed; + bottom: 0; +} + +div.content { + position: absolute; + top: 54px; + left: 8px; + bottom: 25px; + right: 8px; + margin-top: 25px; + overflow: hidden; +} +div.posts { + position: relative; + width: 100%; + height: 100%; +} + +div.posts > a { + width: 128px; + height: 128px; + box-shadow: 2px 2px 6px 0px rgb(0, 0, 0); + margin: 4px; + float: left; + outline: none; + box-shadow: inset 0 0 10px #4c4a4a; +} +div.posts > a > img.thumb { + border: 2px solid black; + transition: .1s ease-out; +} +div.posts > a > img.thumb:hover { + box-shadow: 0px 0px 0px 2px #dac8d2; + border-radius: 5px; + transition: .1s ease-in; +} + +/* fml */ +div#header { + height: 65px; + left: 8px; + right: 8px; + top: 0; + position: absolute; + background-color: #292922; +} +#logoHead { + margin: 6px 0 0 4px; + padding: 0; + font-size: 14px; +} +#logo { + padding: 1px 4px 1px 4px; + height: 48px; +} +#itemInfo { + display: none; + height: 61px; + position: absolute; + left: 200px; + right: 270px; + top: 4px; +} +#itemInfo div.infoText { + margin-top: 3px; +} +#pagePosition, #itemPosition { + position: absolute; + right: 8px; + bottom: 6px; + padding: 0; + color: #7d7b6a; + background-color: #333; +} +#pagePosition span, #itemPosition span { + color: #9d9b8a; +} +#pagePosition { + display: block; +} +#itemPosition { + display: none; +} + +div#wrapper { + display: block; +} +div#itemview { + z-index: 999; + background-color: rgba(0,0,0,0.8); + display: none; +} \ No newline at end of file diff --git a/public/js/f0ck.js b/public/js/f0ck.js index e69de29..e397776 100644 --- a/public/js/f0ck.js +++ b/public/js/f0ck.js @@ -0,0 +1,151 @@ +/* Todo: + * - Event tracker (rt.events) + * - Functions und Events in Module auslagern + */ +import rt from "./rt.js"; +import "./test.js"; + +const calcItems = () => { + const cs = window.getComputedStyle(rt.container.posts[0]); + const height = parseInt(cs.height.replace("px", "")); + const width = parseInt(cs.width.replace("px", "")); + const cols = ~~(width / ( rt.layout.itemsize + rt.layout.margin )); + const rows = ~~(height / ( rt.layout.itemsize + rt.layout.margin )); + rt.container.posts.forEach(e => { + e.style.marginLeft = Math.max((width - (cols * (rt.layout.itemsize + rt.layout.margin)) + rt.layout.margin) / rt.layout.min_rows, 0) * 1.5; + }); + + return { + rows: rows, + cols: cols, + eps: rows * cols, + width: width, + height: height + }; +}; +const getItems = async ({ el, opt = "" }) => { + const tmp = calcItems(); + if(tmp.eps === rt.items.eps) + return; + rt.items.eps = tmp.eps; + el.innerHTML = ""; + const i = await (await fetch(`/api/p?eps=${tmp.eps}&${opt}`)).json(); + + const items = i.items.sort((a, b) => b.id - a.id); + items.forEach(item => { + const _a = document.createElement("a"); + _a.title = item.mime; + _a.href = `#${item.id}`;//`${rt.url}/${item.id}`; + const _img = document.createElement("img"); + _img.classList.add("thumb"); + _img.src = `${rt.url}/t/${item.id}.png`; + _a.insertAdjacentElement("afterbegin", _img); + el.insertAdjacentElement("beforeend", _a); + }); + rt.items.first = items[0].id; + rt.items.last = items[items.length - 1].id; + rt.items.oldest = i.oldest; + rt.items.newest = i.newest; + window.history.pushState(rt.items.first, `f0ck.me! page ${rt.items.first}`, `/page/${rt.items.first}`); + + document.querySelector("#pagePosition").innerHTML = `items ${rt.items.first} - ${rt.items.last}`; +}; + +const scroll = async e => { // uff + if(rt.tmp.scroll) + return; + rt.tmp.scroll = true; + const direction = e.target.id === "up" ? "up" : e.deltaY < 0 ? "up": "down"; + if((direction === "up" && rt.items.first === rt.items.newest) || (direction === "down" && rt.items.last === rt.items.oldest)) + return rt.tmp.scroll = false; + rt.items.eps = 0; + await getItems({ + el: rt.container.posts[direction === "up" ? 0 : 2], + opt: direction === "up" ? `id=${rt.items.first}&order=asc` : `id=${rt.items.last}&order=desc` + }); + rt.container.posts[direction === "up" ? 0 : 2].scrollIntoView({ block: rt.st.block, behavior: "smooth" }); + await new Promise(resolve => setTimeout(resolve, 500)); + + rt.container.posts[1].innerHTML = rt.container.posts[direction === "up" ? 0 : 2].innerHTML; + rt.container.posts[1].scrollIntoView({ block: rt.st.block, behavior: "auto" }); + + rt.tmp.scroll = false; +}; + +const swiper = { + touchStartY: 0, + touchEndY: 0, + minSwipePixels: 30, + detectionZone: undefined, + swiperCallback: () => {}, + init: (detectionZone, callback) => { + swiper.swiperCallback = callback + detectionZone.addEventListener("touchstart", event => { + swiper.touchStartY = event.changedTouches[0].screenY; + }, false); + detectionZone.addEventListener("touchend", event => { + swiper.touchEndY = event.changedTouches[0].screenY; + swiper.handleSwipeGesture(); + }, false); + }, + handleSwipeGesture: () => { + let direction, moved; + if (swiper.touchEndY <= swiper.touchStartY) { + moved = swiper.touchStartY - swiper.touchEndY; + direction = "down"; + } + if (swiper.touchEndY >= swiper.touchStartY) { + moved = swiper.touchEndY - swiper.touchStartY; + direction = "up"; + } + if (moved > swiper.minSwipePixels && direction !== "undefined") + swiper.swipe(direction, moved); + }, + swipe: (direction, movedPixels) => { + const ret = {}; + ret.direction = direction; + ret.movedPixels = movedPixels; + swiper.swiperCallback(ret); + } +}; + +const resize = e => { + e.preventDefault(); + clearTimeout(rt.tmp.resize); + rt.tmp.resize = setTimeout(() => getItems({ + el: rt.container.posts[1], + opt: `id=${rt.items.first + 1}&order=desc` + }), 500); +}; + +// events +swiper.init(rt.container.wrapper, e => scroll({ target: { id: e.direction }})); +document.querySelectorAll("div.pscroll").forEach(p => p.addEventListener("click", scroll)); +document.addEventListener("wheel", scroll); + +(() => { // init + window.addEventListener("resize", resize); + setTimeout(() => { + const pn = parseInt(document.location.pathname.split("/").splice(-1)); + rt.container.posts[1].scrollIntoView({ block: rt.st.block }); // mitte + getItems({ + el: rt.container.posts[1], + opt: pn > 0 ? `id=${pn + 1}&order=desc` : "" + }); + }, 300); +})(); + + + +window.addEventListener("hashchange", e => { + const itemid = parseInt(e.newURL.split("#").slice(-1)); + if(itemid === "NaN") + return rt.container.itemview.style.display = "none"; + + + rt.container.itemview.style.display = "block"; // show itemview + // remove page events + document.removeEventListener("wheel", scroll); + + console.log(itemid); +}); diff --git a/public/js/rt.js b/public/js/rt.js new file mode 100644 index 0000000..c137196 --- /dev/null +++ b/public/js/rt.js @@ -0,0 +1,29 @@ +export default { + layout: { + margin: 6, + min_cols: 3, + min_rows: 4, + itemsize: 130 + }, + st: { + behavior: "smooth", + block: "center" + }, + url: "//f0ck.me", + tmp: { + scroll: false, + resize: null + }, + container: { + wrapper: document.querySelector("div#wrapper"), + itemview: document.querySelector("div#itemview"), + posts: document.querySelectorAll("div.posts") + }, + items: { + first: null, + last: null, + newest: null, + oldest: null, + eps: 0 + } +}; diff --git a/public/js/test.js b/public/js/test.js new file mode 100644 index 0000000..e69de29