diff --git a/package-lock.json b/package-lock.json
index 6711bac..83377cb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4,12 +4,6 @@
"lockfileVersion": 1,
"requires": true,
"dependencies": {
- "commander": {
- "version": "2.20.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
- "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==",
- "optional": true
- },
"cuffeo": {
"version": "git+https://gitfap.de/keinBot/cuffeo.git#d55586ce5520d4119fa0900ef15ce8736fc62364",
"from": "git+https://gitfap.de/keinBot/cuffeo.git"
@@ -19,17 +13,6 @@
"resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz",
"integrity": "sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ=="
},
- "handlebars": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.2.tgz",
- "integrity": "sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==",
- "requires": {
- "neo-async": "^2.6.0",
- "optimist": "^0.6.1",
- "source-map": "^0.6.1",
- "uglify-js": "^3.1.4"
- }
- },
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@@ -53,49 +36,10 @@
"long": "^4.0.0"
}
},
- "minimist": {
- "version": "0.0.10",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
- "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8="
- },
- "neo-async": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.0.tgz",
- "integrity": "sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA=="
- },
- "optimist": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
- "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
- "requires": {
- "minimist": "~0.0.1",
- "wordwrap": "~0.0.2"
- }
- },
"safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- },
- "uglify-js": {
- "version": "3.5.8",
- "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.5.8.tgz",
- "integrity": "sha512-GFSjB1nZIzoIq70qvDRtWRORHX3vFkAnyK/rDExc0BN7r9+/S+Voz3t/fwJuVfjppAMz+ceR2poE7tkhvnVwQQ==",
- "optional": true,
- "requires": {
- "commander": "~2.20.0",
- "source-map": "~0.6.1"
- }
- },
- "wordwrap": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
- "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="
}
}
}
diff --git a/package.json b/package.json
index 5a88831..8e51edd 100644
--- a/package.json
+++ b/package.json
@@ -12,7 +12,6 @@
"license": "ISC",
"dependencies": {
"cuffeo": "git+https://gitfap.de/keinBot/cuffeo.git",
- "handlebars": "^4.1.2",
"mariadb": "^2.0.3"
}
}
diff --git a/public/css/f0ck.css b/public/css/f0ck.css
index e02e83f..2728fc2 100644
--- a/public/css/f0ck.css
+++ b/public/css/f0ck.css
@@ -1,9 +1,3 @@
-/* f0ck.me Stylesheet v2 */
-/* Created in April of 2019 by the notorious and super sexy Alman Abu Ottermann */
-/* This style makes use of the Milligram CSS framework and might not work as expected without! */
-/* Contact: sirx @ f0ck . it */
-/* This style is not meant to be used anywhere else than on f0ck.me or any other f0ck related website! */
-
/*Theming*/
:root {
--primary-color: #302AE6;
@@ -22,108 +16,26 @@
}
/*End of Theming*/
-/* Body */
-body {
+html, body {
+ height: 100%;
+ width: 100%;
+ margin: 0;
+ overflow: hidden;
background-color: var(--bg-color);
color: var(--font-color);
-
- overflow: hidden;
+}
+div.pageWrapper {
height: 100%;
- margin: 0;
- padding: 0;
-}
-/* End of Body */
-
-/* Fieldset & Legend
-legend {
- border-radius: 2px;
- background: black;
- font-family: monospace;
- border: 1px white solid;
- color: white;
-}
-
-fieldset {
- border: 1px solid white;
- padding: 20px;
- background: black;
-}
-End of Fieldset & Legend */
-
-/* NAV */
-button {
- background: #000101;
- border: 1px solid white;
- border-radius: 0px;
- vertical-align: bottom !important;
-}
-
-/* END OF NAV */
-
-/* MISC */
-::-webkit-scrollbar {
- width: 12px;
-}
-
-::-webkit-scrollbar-track {
- -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
- border-radius: 10px;
-}
-
-::-webkit-scrollbar-thumb {
- border-radius: 10px;
- -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5);
-}
-
-/* Flummikram lol */
-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%;
+ display: grid;
+ grid-template-columns: 1fr;
+ grid-template-rows: 0.2fr 2.6fr 0fr;
}
-
-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;
+div#header, div#footer {
+ z-index: 9999;
background-color: #292922;
}
+
#logoHead {
margin: 6px 0 0 4px;
padding: 0;
@@ -147,7 +59,7 @@ div#header {
#pagePosition, #itemPosition {
position: absolute;
right: 8px;
- bottom: 6px;
+ top: 6px;
padding: 0;
color: #7d7b6a;
background-color: #333;
@@ -162,32 +74,21 @@ div#header {
display: none;
}
-div#wrapper {
- display: block;
+div#content {
+ position: relative;
}
-div#itemview {
- z-index: 999;
- background-color: rgba(0,0,0,0.8);
+
+div.wrapper {
display: none;
-
- flex-direction: row;
- width: 100%;
-}
-
-div.items {
- /*position: relative;*/
- flex: 1 1 0px;
-
- width: 100%;
- height: 100%;
-}
-img.item {
position: absolute;
- max-height: 100%;
- max-width: 100%;
top: 0;
- bottom: 0;
left: 0;
- right: 0;
- margin: auto;
+ height: 100%;
+ width: 100%;
+}
+
+div#howtowrapper {
+ overflow: hidden;
+ background-color: rgba(0, 0, 0, 0.9);
+ z-index: 999;
}
diff --git a/public/css/icons.css b/public/css/icons.css
index 6000da6..13239c1 100644
--- a/public/css/icons.css
+++ b/public/css/icons.css
@@ -28,7 +28,7 @@
div.arrow {
- position: fixed;
+ position: absolute;
cursor: pointer;
height: 70px;
width: 70px;
@@ -67,22 +67,25 @@ div.right:before {
}
div.arrow.top {
- top: 80px;
+ top: 10px;
left: 50%;
transform: translateX(-50%);
}
div.arrow.bottom {
- bottom: 80px;
+ bottom: 10px;
left: 50%;
transform: translateX(-50%);
}
div.arrow.left {
- left: 20px;
+ position: fixed !important;
+ left: 10px;
top: 50%;
transform: translateY(-50%);
}
div.arrow.right {
- right: 20px;
+ position: fixed !important;
+ right: 10px;
top: 50%;
transform: translateY(-50%);
}
+
diff --git a/public/css/itemview.css b/public/css/itemview.css
new file mode 100644
index 0000000..fdec8d6
--- /dev/null
+++ b/public/css/itemview.css
@@ -0,0 +1,28 @@
+div#itemwrapper {
+ overflow: hidden;
+ background-color: rgba(0, 0, 0, 0.4);
+ z-index: 999;
+}
+
+div#i_items {
+ width: 300%;
+ height: 100%;
+ overflow: hidden;
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ grid-template-rows: 1fr;
+ grid-template-areas: ". . .";
+}
+div.i_item {
+ overflow: hidden;
+ height: 100%;
+ width: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.item {
+ max-height: 100%;
+ max-width: 100%;
+}
diff --git a/public/css/milligram.min.css b/public/css/milligram.min.css
deleted file mode 100644
index 1051cbf..0000000
--- a/public/css/milligram.min.css
+++ /dev/null
@@ -1,3 +0,0 @@
-*,*:after,*:before{box-sizing:inherit}html{box-sizing:border-box;font-size:62.5%}body{color:#606c76;font-family:'Roboto', 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;font-size:1.6em;font-weight:300;letter-spacing:.01em;line-height:1.6}blockquote{border-left:0.3rem solid #d1d1d1;margin-left:0;margin-right:0;padding:1rem 1.5rem}blockquote *:last-child{margin-bottom:0}.button,button,input[type='button'],input[type='reset'],input[type='submit']{background-color:#9b4dca;border:0.1rem solid #9b4dca;border-radius:.4rem;color:#fff;cursor:pointer;display:inline-block;font-size:1.1rem;font-weight:700;height:3.8rem;letter-spacing:.1rem;line-height:3.8rem;padding:0 3.0rem;text-align:center;text-decoration:none;text-transform:uppercase;white-space:nowrap}.button:focus,.button:hover,button:focus,button:hover,input[type='button']:focus,input[type='button']:hover,input[type='reset']:focus,input[type='reset']:hover,input[type='submit']:focus,input[type='submit']:hover{background-color:#606c76;border-color:#606c76;color:#fff;outline:0}.button[disabled],button[disabled],input[type='button'][disabled],input[type='reset'][disabled],input[type='submit'][disabled]{cursor:default;opacity:.5}.button[disabled]:focus,.button[disabled]:hover,button[disabled]:focus,button[disabled]:hover,input[type='button'][disabled]:focus,input[type='button'][disabled]:hover,input[type='reset'][disabled]:focus,input[type='reset'][disabled]:hover,input[type='submit'][disabled]:focus,input[type='submit'][disabled]:hover{background-color:#9b4dca;border-color:#9b4dca}.button.button-outline,button.button-outline,input[type='button'].button-outline,input[type='reset'].button-outline,input[type='submit'].button-outline{background-color:transparent;color:#9b4dca}.button.button-outline:focus,.button.button-outline:hover,button.button-outline:focus,button.button-outline:hover,input[type='button'].button-outline:focus,input[type='button'].button-outline:hover,input[type='reset'].button-outline:focus,input[type='reset'].button-outline:hover,input[type='submit'].button-outline:focus,input[type='submit'].button-outline:hover{background-color:transparent;border-color:#606c76;color:#606c76}.button.button-outline[disabled]:focus,.button.button-outline[disabled]:hover,button.button-outline[disabled]:focus,button.button-outline[disabled]:hover,input[type='button'].button-outline[disabled]:focus,input[type='button'].button-outline[disabled]:hover,input[type='reset'].button-outline[disabled]:focus,input[type='reset'].button-outline[disabled]:hover,input[type='submit'].button-outline[disabled]:focus,input[type='submit'].button-outline[disabled]:hover{border-color:inherit;color:#9b4dca}.button.button-clear,button.button-clear,input[type='button'].button-clear,input[type='reset'].button-clear,input[type='submit'].button-clear{background-color:transparent;border-color:transparent;color:#9b4dca}.button.button-clear:focus,.button.button-clear:hover,button.button-clear:focus,button.button-clear:hover,input[type='button'].button-clear:focus,input[type='button'].button-clear:hover,input[type='reset'].button-clear:focus,input[type='reset'].button-clear:hover,input[type='submit'].button-clear:focus,input[type='submit'].button-clear:hover{background-color:transparent;border-color:transparent;color:#606c76}.button.button-clear[disabled]:focus,.button.button-clear[disabled]:hover,button.button-clear[disabled]:focus,button.button-clear[disabled]:hover,input[type='button'].button-clear[disabled]:focus,input[type='button'].button-clear[disabled]:hover,input[type='reset'].button-clear[disabled]:focus,input[type='reset'].button-clear[disabled]:hover,input[type='submit'].button-clear[disabled]:focus,input[type='submit'].button-clear[disabled]:hover{color:#9b4dca}code{background:#f4f5f6;border-radius:.4rem;font-size:86%;margin:0 .2rem;padding:.2rem .5rem;white-space:nowrap}pre{background:#f4f5f6;border-left:0.3rem solid #9b4dca;overflow-y:hidden}pre>code{border-radius:0;display:block;padding:1rem 1.5rem;white-space:pre}hr{border:0;border-top:0.1rem solid #f4f5f6;margin:3.0rem 0}input[type='email'],input[type='number'],input[type='password'],input[type='search'],input[type='tel'],input[type='text'],input[type='url'],input[type='color'],input[type='date'],input[type='month'],input[type='week'],input[type='datetime'],input[type='datetime-local'],input:not([type]),textarea,select{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;border:0.1rem solid #d1d1d1;border-radius:.4rem;box-shadow:none;box-sizing:inherit;height:3.8rem;padding:.6rem 1.0rem;width:100%}input[type='email']:focus,input[type='number']:focus,input[type='password']:focus,input[type='search']:focus,input[type='tel']:focus,input[type='text']:focus,input[type='url']:focus,input[type='color']:focus,input[type='date']:focus,input[type='month']:focus,input[type='week']:focus,input[type='datetime']:focus,input[type='datetime-local']:focus,input:not([type]):focus,textarea:focus,select:focus{border-color:#9b4dca;outline:0}select{background:url('data:image/svg+xml;utf8,') center right no-repeat;padding-right:3.0rem}select:focus{background-image:url('data:image/svg+xml;utf8,')}textarea{min-height:6.5rem}label,legend{display:block;font-size:1.6rem;font-weight:700;margin-bottom:.5rem}fieldset{border-width:0;padding:0}input[type='checkbox'],input[type='radio']{display:inline}.label-inline{display:inline-block;font-weight:normal;margin-left:.5rem}.container{margin:0 auto;max-width:112.0rem;padding:0 2.0rem;position:relative;width:100%}.row{display:flex;flex-direction:column;padding:0;width:100%}.row.row-no-padding{padding:0}.row.row-no-padding>.column{padding:0}.row.row-wrap{flex-wrap:wrap}.row.row-top{align-items:flex-start}.row.row-bottom{align-items:flex-end}.row.row-center{align-items:center}.row.row-stretch{align-items:stretch}.row.row-baseline{align-items:baseline}.row .column{display:block;flex:1 1 auto;margin-left:0;max-width:100%;width:100%}.row .column.column-offset-10{margin-left:10%}.row .column.column-offset-20{margin-left:20%}.row .column.column-offset-25{margin-left:25%}.row .column.column-offset-33,.row .column.column-offset-34{margin-left:33.3333%}.row .column.column-offset-50{margin-left:50%}.row .column.column-offset-66,.row .column.column-offset-67{margin-left:66.6666%}.row .column.column-offset-75{margin-left:75%}.row .column.column-offset-80{margin-left:80%}.row .column.column-offset-90{margin-left:90%}.row .column.column-10{flex:0 0 10%;max-width:10%}.row .column.column-20{flex:0 0 20%;max-width:20%}.row .column.column-25{flex:0 0 25%;max-width:25%}.row .column.column-33,.row .column.column-34{flex:0 0 33.3333%;max-width:33.3333%}.row .column.column-40{flex:0 0 40%;max-width:40%}.row .column.column-50{flex:0 0 50%;max-width:50%}.row .column.column-60{flex:0 0 60%;max-width:60%}.row .column.column-66,.row .column.column-67{flex:0 0 66.6666%;max-width:66.6666%}.row .column.column-75{flex:0 0 75%;max-width:75%}.row .column.column-80{flex:0 0 80%;max-width:80%}.row .column.column-90{flex:0 0 90%;max-width:90%}.row .column .column-top{align-self:flex-start}.row .column .column-bottom{align-self:flex-end}.row .column .column-center{-ms-grid-row-align:center;align-self:center}@media (min-width: 40rem){.row{flex-direction:row;margin-left:-1.0rem;width:calc(100% + 2.0rem)}.row .column{margin-bottom:inherit;padding:0 1.0rem}}a{color:#9b4dca;text-decoration:none}a:focus,a:hover{color:#606c76}dl,ol,ul{list-style:none;margin-top:0;padding-left:0}dl dl,dl ol,dl ul,ol dl,ol ol,ol ul,ul dl,ul ol,ul ul{font-size:90%;margin:1.5rem 0 1.5rem 3.0rem}ol{list-style:decimal inside}ul{list-style:circle inside}.button,button,dd,dt,li{margin-bottom:1.0rem}fieldset,input,select,textarea{margin-bottom:1.5rem}blockquote,dl,figure,form,ol,p,pre,table,ul{margin-bottom:2.5rem}table{border-spacing:0;width:100%}td,th{border-bottom:0.1rem solid #e1e1e1;padding:1.2rem 1.5rem;text-align:left}td:first-child,th:first-child{padding-left:0}td:last-child,th:last-child{padding-right:0}b,strong{font-weight:bold}p{margin-top:0}h1,h2,h3,h4,h5,h6{font-weight:300;letter-spacing:-.1rem;margin-bottom:2.0rem;margin-top:0}h1{font-size:4.6rem;line-height:1.2}h2{font-size:3.6rem;line-height:1.25}h3{font-size:2.8rem;line-height:1.3}h4{font-size:2.2rem;letter-spacing:-.08rem;line-height:1.35}h5{font-size:1.8rem;letter-spacing:-.05rem;line-height:1.5}h6{font-size:1.6rem;letter-spacing:0;line-height:1.4}img{max-width:100%}.clearfix:after{clear:both;content:' ';display:table}.float-left{float:left}.float-right{float:right}
-
-/*# sourceMappingURL=milligram.min.css.map */
\ No newline at end of file
diff --git a/public/css/pageview.css b/public/css/pageview.css
new file mode 100644
index 0000000..3369c53
--- /dev/null
+++ b/public/css/pageview.css
@@ -0,0 +1,34 @@
+div#pagewrapper {
+ display: block;
+ overflow: hidden;
+}
+
+div#p_items {
+ overflow: hidden;
+ height: 100%;
+ width: 100%;
+}
+div.p_item {
+ height: 100%;
+ width: 100%;
+}
+
+
+div.p_item > 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.p_item > a > img.thumb {
+ border: 2px solid black;
+ transition: .1s ease-out;
+}
+div.p_item > a > img.thumb:hover {
+ box-shadow: 0px 0px 0px 2px #dac8d2;
+ border-radius: 5px;
+ transition: .1s ease-in;
+}
diff --git a/public/js/events.js b/public/js/events.js
new file mode 100644
index 0000000..2807854
--- /dev/null
+++ b/public/js/events.js
@@ -0,0 +1,150 @@
+import rt from "./rt.js";
+import lib from "./lib.js";
+
+const events = {};
+events.wheel = {
+ page: async e => {
+ if(rt.scroll)
+ return;
+ rt.scroll = true;
+ const deltaY = e.target.id === "up" ? -1 : e.deltaY < 0 ? -1: 1; // -1 up, 1 down
+
+ if((deltaY === -1 && rt.items.first === rt.items.newest) || (deltaY === 1 && rt.items.last === rt.items.oldest))
+ return rt.scroll = false;
+ rt.items.eps = 0;
+ await lib.getItems({
+ el: rt.ct.wrapper.pages[deltaY === -1 ? 0 : 2],
+ opt: deltaY === -1 ? `id=${rt.items.first}&order=asc` : `id=${rt.items.last}&order=desc`
+ });
+ rt.ct.wrapper.pages[deltaY === -1 ? 0 : 2].scrollIntoView({ block: rt.vars.block, behavior: "smooth" });
+ await new Promise(resolve => setTimeout(resolve, rt.vars.cd));
+
+ rt.ct.wrapper.pages[1].innerHTML = rt.ct.wrapper.pages[deltaY === -1 ? 0 : 2].innerHTML;
+ rt.ct.wrapper.pages[1].scrollIntoView({ block: rt.vars.block });
+
+ rt.scroll = false;
+ },
+ item: async e => {
+ if(rt.scroll)
+ return;
+ const deltaY = e.target.id === "left" ? -1 : e.deltaY < 0 ? -1: 1; // -1 left, 1 right
+ if((deltaY === -1 && rt.items.act === rt.items.first) || (deltaY === 1 && rt.items.act === rt.items.last))
+ return rt.scroll = false;
+ window.location = `${window.location.pathname}#${rt.items.act - deltaY}`;
+ }
+};
+events.resize = {
+ page: async e => {
+ e.preventDefault();
+ clearTimeout(rt.tmp.resize);
+ lib.calcItems();
+ rt.tmp.resize = setTimeout(() => lib.getItems({
+ el: rt.ct.wrapper.pages[1],
+ opt: `id=${rt.items.first + 1}&order=desc`
+ }), rt.vars.cd);
+
+ lib.scrolltomiddle(rt.ct.wrapper.pages);
+ },
+ item: async e => {
+ lib.scrolltomiddle(rt.ct.wrapper.items);
+ }
+};
+events.hashchange = async e => {
+ if(rt.scroll)
+ return;
+ rt.scroll = true;
+
+ if(!rt.tmp.hash)
+ return rt.tmp.hash = true;
+ const itemid = parseInt((e.newURL?e.newURL:e.detail.newURL).split("#").slice(-1));
+ if(!itemid || itemid <= 0) // failover oder so
+ return lib.showLayer("page");
+
+ const next = rt.items.act === null || rt.items.act === itemid ? 1 : rt.items.act > itemid ? 2 : 0;
+ rt.ct.header.itempos.innerHTML = `item ${itemid}`;
+ const item = await (await fetch(`${rt.api}/item/${itemid}`)).json();
+ item.dest = item.dest.replace(/^\./, "");
+
+ rt.ct.header.infos.source.href = item.src;
+ rt.ct.header.infos.source.innerHTML = item.srchost;
+ rt.ct.header.infos.channel.innerHTML = `${item.usernetwork} ${item.userchannel}`;
+ rt.ct.header.infos.title.innerHTML = `${item.mime} (${item.size})`;
+ rt.ct.header.infos.nick.innerHTML = item.username;
+
+ lib.showLayer("item", next === 1);
+
+ rt.ct.wrapper.pages[1].querySelectorAll("a > img").forEach(e => {
+ e.style.boxShadow = null;
+ e.style.borderRadius = null;
+ e.style.transition = ".1s ease-out";
+ });
+ setTimeout(() => {
+ rt.ct.wrapper.pages[1].querySelector(`a[href='#${itemid}'] > img`).style.boxShadow = "0px 0px 0px 2px #dac8d2";
+ rt.ct.wrapper.pages[1].querySelector(`a[href='#${itemid}'] > img`).style.borderRadius = "5px";
+ rt.ct.wrapper.pages[1].querySelector(`a[href='#${itemid}'] > img`).style.transition = ".1s ease-in";
+ }, 50);
+
+ let el;
+ switch(item.mime) {
+ case "audio/flac":
+ case "audio/mpeg":
+ case "audio/ogg":
+ case "audio/x-flac": // audios
+ el = document.createElement("audio");
+ el.src = `${rt.url}${item.dest}`;
+ el.type = item.mime;
+ el.autoplay = true;
+ el.controls = true;
+ el.loop = true;
+ break;
+ case "image/gif":
+ case "image/jpeg":
+ case "image/png": // images
+ el = document.createElement("img");
+ el.src = `${rt.url}${item.dest}`;
+ break;
+ case "video/mp4":
+ case "video/quicktime":
+ case "video/webm":
+ case "video/ogv": // videos
+ el = document.createElement("video");
+ el.src = `${rt.url}${item.dest}`;
+ el.type = item.mime;
+ el.autoplay = true;
+ el.controls = true;
+ el.loop = true;
+ break;
+ default:
+ alert("lol hacker");
+ break;
+ }
+
+ el.classList.add("item");
+
+ rt.ct.wrapper.items[next].insertAdjacentElement("afterbegin", el);
+
+ rt.ct.wrapper.items[next].scrollIntoView({ block: rt.vars.block, behavior: "smooth" });
+
+ rt.items.prev = item.prev;
+ rt.items.next = item.next;
+ rt.items.act = item.id;
+
+ await new Promise(resolve => setTimeout(resolve, rt.vars.cd));
+
+ if(next !== 1) {
+ document.querySelector("div#i_items").removeChild(rt.ct.wrapper.items[next === 0 ? 2 : 0]);
+ const newdiv = document.createElement("div");
+ newdiv.classList.add("i_item");
+ document.querySelector("div#i_items").insertAdjacentElement((next === 0 ? "afterbegin" : "beforeend"), newdiv);
+
+ rt.ct.wrapper.items = document.querySelectorAll("div.i_item");
+ }
+
+ lib.scrolltomiddle(rt.ct.wrapper.items);
+ rt.ct.wrapper.items[0].innerHTML = "";
+ rt.ct.wrapper.items[2].innerHTML = "";
+
+ rt.scroll = false;
+};
+
+export default events;
diff --git a/public/js/f0ck.js b/public/js/f0ck.js
index ff00ab0..2ac3897 100644
--- a/public/js/f0ck.js
+++ b/public/js/f0ck.js
@@ -1,170 +1,33 @@
-/* Todo:
- * - Event tracker (rt.events)
- * - Functions und Events in Module auslagern
- */
import rt from "./rt.js";
-import "./test.js";
+import events from "./events.js";
+import lib from "./lib.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();
+(async () => {
+ lib.showLayer("page");
+ window.addEventListener("hashchange", events.hashchange);
- 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);
+ const debug = document.querySelectorAll("span#debug > a");
+ debug[0].addEventListener("click", () => { // page
+ lib.showLayer("page");
});
- 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`
+ debug[1].addEventListener("click", () => { // item
+ lib.showLayer("item");
});
- 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.arrow")].filter(e => ["up", "down"].includes(e.id)).forEach(p => p.addEventListener("click", scroll));
-document.addEventListener("wheel", scroll);
-
-(() => { // init
- window.addEventListener("resize", resize);
+ debug[2].addEventListener("click", () => { // item
+ lib.showLayer("howto");
+ });
+
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],
+ const hash = document.location.hash;
+ lib.scrolltomiddle(rt.ct.wrapper.pages);
+ lib.getItems({
+ el: rt.ct.wrapper.pages[1],
opt: pn > 0 ? `id=${pn + 1}&order=desc` : ""
});
+
+ if(hash)
+ window.dispatchEvent(new CustomEvent("hashchange", { detail: { newURL: hash } }));
}, 300);
+
})();
-
-
-
-window.addEventListener("hashchange", async e => {
- const itemid = parseInt(e.newURL.split("#").slice(-1));
- if(itemid <= 0) { // failover
- rt.container.itemview.style.display = "none";
- return false;
- }
-
- rt.container.itemview.style.display = "flex"; // show itemview
- rt.container.header.itempos.style.display = "block";
- rt.container.header.pagepos.style.display = "none";
- rt.container.header.iteminfo.style.display = "block";
-
- rt.container.header.itempos.innerHTML = `item ${itemid}`;
-
- const item = await (await fetch(`/api/item/${itemid}`)).json();
- console.log(item);
-
- rt.container.header.infos.source.href = item.src;
- rt.container.header.infos.source.innerHTML = item.srchost;
- rt.container.header.infos.channel.innerHTML = `${item.usernetwork} ${item.userchannel}`;
- rt.container.header.infos.title.innerHTML = `${item.mime} (${item.size})`;
- rt.container.header.infos.nick.innerHTML = item.username;
-
- rt.container.items[1].innerHTML = ``;
- rt.container.items[1].scrollIntoView({ block: rt.st.block }); // mitte
-
- // remove page events
- document.removeEventListener("wheel", scroll);
-
- console.log(itemid);
-});
diff --git a/public/js/f0ck.min.js b/public/js/f0ck.min.js
new file mode 100644
index 0000000..532df62
--- /dev/null
+++ b/public/js/f0ck.min.js
@@ -0,0 +1 @@
+import rt from"./rt.js";import events from"./events.js";import lib from"./lib.js";(async()=>{lib.showLayer("page"),window.addEventListener("hashchange",events.hashchange);const e=document.querySelectorAll("span#debug > a");e[0].addEventListener("click",()=>{lib.showLayer("page")}),e[1].addEventListener("click",()=>{lib.showLayer("item")}),e[2].addEventListener("click",()=>{lib.showLayer("howto")}),setTimeout(()=>{const e=parseInt(document.location.pathname.split("/").splice(-1)),t=document.location.hash;lib.scrolltomiddle(rt.ct.wrapper.pages),lib.getItems({el:rt.ct.wrapper.pages[1],opt:e>0?`id=${e+1}&order=desc`:""}),t&&window.dispatchEvent(new CustomEvent("hashchange",{detail:{newURL:t}}))},300)})();
\ No newline at end of file
diff --git a/public/js/lib.js b/public/js/lib.js
new file mode 100644
index 0000000..db33b48
--- /dev/null
+++ b/public/js/lib.js
@@ -0,0 +1,121 @@
+import rt from "./rt.js";
+import events from "./events.js";
+
+const calcItems = () => {
+ const cs = window.getComputedStyle(rt.ct.content);
+ 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.ct.wrapper.pages.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 + "px";
+ e.style.paddingTop = Math.max((height - (rows * (rt.layout.itemsize + rt.layout.margin)) + rt.layout.margin) / rt.layout.min_rows, 0) + "px";
+ });
+
+ 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(`${rt.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;
+
+ rt.tmp.hash = false;
+ window.history.pushState(rt.items.first, `f0ck.me! page ${rt.items.first}`, `/page/${rt.items.first}${(window.location.hash?window.location.hash:"")}`);
+ rt.tmp.hash = true;
+
+ rt.ct.header.pagepos.innerHTML = `items ${rt.items.first} - ${rt.items.last}`;
+};
+
+const scrolltomiddle = el => {
+ el[0].scrollIntoView({ block: rt.vars.block });
+ el[2].scrollIntoView({ block: rt.vars.block });
+ el[1].scrollIntoView({ block: rt.vars.block });
+};
+
+const showLayer = (layer, scroll = true) => {
+ // hide all pages
+ for(let e in rt.ct.tabs)
+ rt.ct.tabs[e].style.display = "none";
+ // remove all events for reassigning
+ document.removeEventListener("wheel", events.wheel.item);
+ document.removeEventListener("wheel", events.wheel.page);
+ window.removeEventListener("resize", events.resize.item);
+ window.removeEventListener("resize", events.resize.page);
+ [...rt.ct.arrows] // remove itembuttons
+ .filter(e => ["left", "right"].includes(e.id))
+ .forEach(p => p.removeEventListener("click", events.wheel.item));
+ [...rt.ct.arrows] // remove pagebuttons
+ .filter(e => ["up", "down"].includes(e.id))
+ .forEach(p => p.removeEventListener("click", events.wheel.page));
+
+ switch(layer) {
+ case "page":
+ rt.ct.tabs.item.style.display = "none";
+ rt.ct.tabs.howto.style.display = "none";
+ document.addEventListener("wheel", events.wheel.page);
+ window.addEventListener("resize", events.resize.page);
+ [...rt.ct.arrows] // add pagebuttons
+ .filter(e => ["up", "down"].includes(e.id))
+ .forEach(p => p.addEventListener("click", events.wheel.page));
+
+ if(scroll)
+ scrolltomiddle(rt.ct.wrapper.pages);
+
+ rt.ct.header.pagepos.style.display = "block";
+ rt.ct.header.itempos.style.display = "none";
+ rt.ct.header.iteminfo.style.display = "none";
+ break;
+ case "item":
+ rt.ct.tabs.item.style.display = "block";
+ document.addEventListener("wheel", events.wheel.item);
+ window.addEventListener("resize", events.resize.item);
+ [...rt.ct.arrows] // add itembuttons
+ .filter(e => ["left", "right"].includes(e.id))
+ .forEach(p => p.addEventListener("click", events.wheel.item));
+
+ if(scroll)
+ scrolltomiddle(rt.ct.wrapper.items);
+
+ rt.ct.header.pagepos.style.display = "none";
+ rt.ct.header.itempos.style.display = "block";
+ rt.ct.header.iteminfo.style.display = "block";
+ break;
+ case "howto":
+ rt.ct.tabs.howto.style.display = "block";
+ break;
+ }
+};
+
+export default { // oof
+ calcItems: calcItems,
+ getItems: getItems,
+ showLayer: showLayer,
+ scrolltomiddle: scrolltomiddle
+};
diff --git a/public/js/rt.js b/public/js/rt.js
index 7fa1458..fcd9326 100644
--- a/public/js/rt.js
+++ b/public/js/rt.js
@@ -5,18 +5,38 @@ export default {
min_rows: 4,
itemsize: 130
},
- st: {
- behavior: "smooth",
- block: "center"
- },
url: "//f0ck.me",
+ api: "//dev.f0ck.me/api",
+ vars: {
+ cd: 700,
+ block: "start"
+ },
tmp: {
scroll: false,
- resize: null
+ resize: null,
+ hash: true
},
- container: {
- wrapper: document.querySelector("div#wrapper"),
- itemview: document.querySelector("div#itemview"),
+ items: {
+ first: null,
+ last: null,
+ newest: null,
+ oldest: null,
+ next: null,
+ prev: null,
+ act: null,
+ eps: 0
+ },
+ ct: {
+ content: document.querySelector("div#content"),
+ wrapper: {
+ pages: document.querySelectorAll("div.p_item"),
+ items: document.querySelectorAll("div.i_item")
+ },
+ tabs: {
+ item: document.querySelector("div#itemwrapper"),
+ howto: document.querySelector("div#howtowrapper")
+ },
+ arrows: document.querySelectorAll("div.arrow"),
header: {
iteminfo: document.querySelector("div#itemInfo"),
pagepos: document.querySelector("div#pagePosition"),
@@ -28,15 +48,6 @@ export default {
nick: document.querySelector("span#itemNick"),
channel: document.querySelector("span#itemChannel")
}
- },
- items: document.querySelectorAll("div.items"),
- 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
deleted file mode 100644
index e69de29..0000000
diff --git a/src/inc/routes/inc/index.mjs b/src/inc/routes/inc/index.mjs
deleted file mode 100644
index 1f38d23..0000000
--- a/src/inc/routes/inc/index.mjs
+++ /dev/null
@@ -1,3 +0,0 @@
-export const queries = {
- items: "select id, mime from items order by id desc limit 72"
-};
diff --git a/src/inc/routes/index.mjs b/src/inc/routes/index.mjs
index b1ea508..478e005 100644
--- a/src/inc/routes/index.mjs
+++ b/src/inc/routes/index.mjs
@@ -1,25 +1,10 @@
import router from "../router";
import fs from "fs";
-import sql from "../sql";
-import handlebars from "handlebars";
-import { queries } from "./inc/index";
-
-const template = fs.readFileSync("./views/index.hbs", "utf-8");
+const tpl = fs.readFileSync("./views/index.html", "utf-8");
router.get(/^\/(page\/[0-9]+)?$/, async (req, res) => {
- const db = await sql.getConnection();
-
- try {
- const rows = await db.query(queries.items);
- const tpl = handlebars.compile(template);
- res
- .writeHead(200, { 'Content-Type': 'text/html' })
- .end(tpl({ items: rows, debug: JSON.stringify(req.url, null, 2) }));
- } catch(err) {
- res
- .writeHead(500)
- .end(JSON.stringify(err), 'utf-8');
- }
- db.end();
+ res
+ .writeHead(200, { 'Content-Type': 'text/html' })
+ .end(tpl);
});
diff --git a/views/index.hbs b/views/index.hbs
deleted file mode 100644
index 3d8145b..0000000
--- a/views/index.hbs
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
-
More information: n0xy.net
+Constitution:
+f0ck specific rules:
+f0ck will f0ck any media link posted in the channel ending with: jpg|gif|png|webm|mp3|mp4|ogg|flac
+If you don't want f0ck to f0ck it put !ignore behind your link. Example: https://retard-journal.com/stupidshit.png !ignore +
f0ck will only f0ck media links with the maximum size of 80MB
+