blah
This commit is contained in:
		
							
								
								
									
										175
									
								
								test1/f0ck.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								test1/f0ck.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,175 @@
 | 
			
		||||
class f0ck {
 | 
			
		||||
  constructor(hash = "") {
 | 
			
		||||
    /*this.tpl = {
 | 
			
		||||
      row: ({ rowid, items }) => `<div class="row" data-row="${rowid}">${items}</div>`,
 | 
			
		||||
      item: ({ id, title, stamp }) => `<a href="//f0ck.me/${id}" data-stamp="${stamp}" class="thumb" style="background-image:url('//f0ck.me/t/${id}.png')"></a>`,
 | 
			
		||||
    };*/
 | 
			
		||||
 | 
			
		||||
    this.tpl = {
 | 
			
		||||
      row: ({ rowid, items }) => `<div class="row" data-row="${rowid}">${items}</div>`,
 | 
			
		||||
      item: ({ stamp }) => `<a href="#" data-stamp="${stamp}" class="thumb" style="background-color: #0f0;"></a>`,
 | 
			
		||||
    };
 | 
			
		||||
    this._layout = {
 | 
			
		||||
      items: {
 | 
			
		||||
        size: 128,
 | 
			
		||||
        gutter: 8
 | 
			
		||||
      },
 | 
			
		||||
      min_margin: 16,
 | 
			
		||||
      min_rows: 2,
 | 
			
		||||
      min_cols: 3
 | 
			
		||||
    };
 | 
			
		||||
    this.tmp = {
 | 
			
		||||
      first: 0,
 | 
			
		||||
      last: 0
 | 
			
		||||
    }
 | 
			
		||||
    this._lastmode = "desc";
 | 
			
		||||
    this.scrollrows = 4;
 | 
			
		||||
    this._dims = null;
 | 
			
		||||
    this.init_events();
 | 
			
		||||
    this._scroll = false;
 | 
			
		||||
    this._items = new Map();
 | 
			
		||||
    this.tmphash = null;
 | 
			
		||||
    this.hash = hash; //setter
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  render(tmp = null) {
 | 
			
		||||
    if(tmp !== null) {
 | 
			
		||||
      tmp.forEach(e => {
 | 
			
		||||
        this._items.set(e.stamp, e);
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      /*let tmprow = "";
 | 
			
		||||
      for(let rows = 0; rows < this._dims.rows; rows++) {
 | 
			
		||||
        tmprow += [{ }]
 | 
			
		||||
        for(let cols = 0; cols < this._dims.cols; cols++) {
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
      }*/
 | 
			
		||||
 | 
			
		||||
      
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  init_events() {
 | 
			
		||||
    let that = this;
 | 
			
		||||
    function resize() {
 | 
			
		||||
      let rows = Math.max(~~((window.innerHeight - that._layout.min_margin + that._layout.items.size) / (that._layout.items.size + that._layout.items.gutter)), that._layout.min_rows);
 | 
			
		||||
      let cols = Math.max(~~((window.innerWidth - that._layout.min_margin) / (that._layout.items.size + that._layout.items.gutter)), that._layout.min_cols);
 | 
			
		||||
      let pageWidth = cols * (that._layout.items.size + that._layout.items.gutter);
 | 
			
		||||
      let margin = Math.max((window.innerWidth - pageWidth + that._layout.items.gutter) / that._layout.min_rows, 0);
 | 
			
		||||
      let page = document.querySelector("div#page");
 | 
			
		||||
      page.style.width = pageWidth;
 | 
			
		||||
      page.style.marginLeft = margin;
 | 
			
		||||
      that._dims = {
 | 
			
		||||
        rows: rows,
 | 
			
		||||
        cols: cols,
 | 
			
		||||
        eps: rows * cols,
 | 
			
		||||
        pageWidth: pageWidth,
 | 
			
		||||
        margin: margin
 | 
			
		||||
      };
 | 
			
		||||
      that.render();
 | 
			
		||||
    }
 | 
			
		||||
    resize();
 | 
			
		||||
 | 
			
		||||
    function scroll(e) {
 | 
			
		||||
      if(e.preventDefault)
 | 
			
		||||
        e.preventDefault();
 | 
			
		||||
      let deltaY = e.deltaY < 0?-1:1; // - up, + down
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
    window.addEventListener('resize', resize); // onresize
 | 
			
		||||
    document.addEventListener("wheel", scroll); // mousewheel
 | 
			
		||||
    document.querySelectorAll("div.pscroll").forEach(elem => elem.addEventListener("click", e => scroll({ deltaY: e.target.id === "up"?-1:1 }))); // buttons
 | 
			
		||||
    window.addEventListener("hashchange", () => { this.hash = window.location.hash }, false); // hashchange
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  set hash(val) {
 | 
			
		||||
    console.log("hash changed");
 | 
			
		||||
    this.tmphash = this.getlink(val);
 | 
			
		||||
    this.firstrun = false;
 | 
			
		||||
    fetch(`/api/`, {
 | 
			
		||||
      headers: {
 | 
			
		||||
        'Accept': 'application/json',
 | 
			
		||||
        'Content-Type': 'application/json'
 | 
			
		||||
      },
 | 
			
		||||
      method: 'POST',
 | 
			
		||||
      body: JSON.stringify(this.tmphash)
 | 
			
		||||
    })
 | 
			
		||||
    .then(res => {
 | 
			
		||||
      if(res.status === 200)
 | 
			
		||||
        return res.json();
 | 
			
		||||
      else
 | 
			
		||||
        return { error: true };
 | 
			
		||||
    })
 | 
			
		||||
    .then(data => {
 | 
			
		||||
      if(!data.error) {
 | 
			
		||||
        this.tmp = {
 | 
			
		||||
          first: data.meta.atFirst,
 | 
			
		||||
          last: data.meta.atLast
 | 
			
		||||
        };
 | 
			
		||||
        //const tmpmap = new Map();
 | 
			
		||||
        //data.items.forEach(e => tmpmap.set(e.stamp, e));
 | 
			
		||||
        //this.render(tmpmap);
 | 
			
		||||
        this.render(data.items);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  getlink(tmp) {
 | 
			
		||||
    const tpl = {
 | 
			
		||||
      user: ({ user, mime, last }) => `user,${user},${mime},${last}`,
 | 
			
		||||
      mime: ({ user, mime, last }) => `mime,${mime},${user},${last}`,
 | 
			
		||||
      new: ({ user, mime, last }) => `items,${last}`,
 | 
			
		||||
    };
 | 
			
		||||
    let blah = {
 | 
			
		||||
      mode: "",
 | 
			
		||||
      user: "",
 | 
			
		||||
      mime: "",
 | 
			
		||||
      last: 0,
 | 
			
		||||
      post: 0
 | 
			
		||||
    };
 | 
			
		||||
    let api = "/api/";
 | 
			
		||||
 | 
			
		||||
    if(!tmp.match(/\,/)) {
 | 
			
		||||
      tmp = "#new";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    tmp = (tmp.match(/,/)?tmp:`${tmp},`).substr(1).split(",");
 | 
			
		||||
    const args = {
 | 
			
		||||
      l: tmp[0].split("/"),
 | 
			
		||||
      r: tmp[1].split("/")
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    blah.mode = ( args.l[0].length === 0 )? "new" : args.l[0];
 | 
			
		||||
    blah.last = parseInt(args.r[0]) || 0;
 | 
			
		||||
    blah.post = parseInt(args.r[1]) || 0;
 | 
			
		||||
    switch(blah.mode) {
 | 
			
		||||
      case "user":
 | 
			
		||||
        blah.user = ( args.l[1] )? args.l[1] : "";
 | 
			
		||||
        blah.mime = ( args.l[2] )? args.l[2] : "";
 | 
			
		||||
      break;
 | 
			
		||||
      case "mime":
 | 
			
		||||
        blah.user = ( args.l[2] )? args.l[2] : "";
 | 
			
		||||
        blah.mime = ( args.l[1] )? args.l[1] : "";
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    console.log(this._lastmode);
 | 
			
		||||
    return {
 | 
			
		||||
      mode: blah.mode,
 | 
			
		||||
      user: blah.user,
 | 
			
		||||
      stamp: blah.last,
 | 
			
		||||
      mime: blah.mime,
 | 
			
		||||
      eps: this._dims.eps,
 | 
			
		||||
      sort: this._lastmode
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getKey(_map, _search) {
 | 
			
		||||
  let i = 0;
 | 
			
		||||
  for(let [key] of _map) {
 | 
			
		||||
    if(key === _search)
 | 
			
		||||
      return i;
 | 
			
		||||
    i++;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								test1/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								test1/index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
<!doctype blah>
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
  <title>Test 1</title>
 | 
			
		||||
  <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1" />
 | 
			
		||||
  <link href="./style.css" rel="stylesheet" />
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
  <div class="navbar">
 | 
			
		||||
    <a href="./">reload</a> | 
 | 
			
		||||
    <a href="#" data-id="1">debug 1</a> | 
 | 
			
		||||
    <a href="#" data-id="2">page 2</a> | 
 | 
			
		||||
    <a href="#" data-id="3">page 3</a>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
  <div class="pscroll" id="up"></div>
 | 
			
		||||
 | 
			
		||||
  <div id="page">
 | 
			
		||||
    <div id="thumbs" style="top: 0;"></div>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
  <div class="pscroll" id="down"></div>
 | 
			
		||||
 | 
			
		||||
  <script src="./f0ck.js"></script>
 | 
			
		||||
  <script>
 | 
			
		||||
    window.onload = () => {
 | 
			
		||||
      let f = new f0ck(window.location.hash);
 | 
			
		||||
    };
 | 
			
		||||
  </script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										26
									
								
								test1/script.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								test1/script.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
$(document).ready(() => {
 | 
			
		||||
  $(window).on('resize', () => {
 | 
			
		||||
    let rows = Math.max(Math.floor(($(window).height() - 16 + 128) / (128 + 8)), 2);
 | 
			
		||||
    let cols = Math.max(Math.floor(($(window).width() - 16) / (128 + 8)), 3);
 | 
			
		||||
    let pageWidth = cols * (128 + 8);
 | 
			
		||||
    let margin = Math.max(($(window).width() - pageWidth + 8) / 2, 0);
 | 
			
		||||
    $("div#page").css({
 | 
			
		||||
      'width': pageWidth,
 | 
			
		||||
      'margin-left': margin
 | 
			
		||||
    });
 | 
			
		||||
  }).resize();
 | 
			
		||||
 | 
			
		||||
  var scroll = false;
 | 
			
		||||
  $("body").on('DOMMouseScroll mousewheel', function(e) {
 | 
			
		||||
    e.preventDefault();
 | 
			
		||||
    if(!scroll) {
 | 
			
		||||
      scroll = true;
 | 
			
		||||
      $("#thumbs").animate({
 | 
			
		||||
        top: `${(parseInt($("#thumbs").css("top").replace("px","")) + (e.deltaY * 128))}px`
 | 
			
		||||
      }, 200, () => {
 | 
			
		||||
        scroll = false;
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										96
									
								
								test1/style.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								test1/style.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,96 @@
 | 
			
		||||
* {
 | 
			
		||||
  padding: 0;
 | 
			
		||||
  margin: 0;
 | 
			
		||||
}
 | 
			
		||||
html, body {
 | 
			
		||||
  margin: 0;
 | 
			
		||||
  padding: 0;
 | 
			
		||||
  background-color: #262626;
 | 
			
		||||
  position: relative;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  color: #fff;
 | 
			
		||||
  font-family: Helvetica, Arial, sans-serif;
 | 
			
		||||
  font-size: 12px;
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
}
 | 
			
		||||
body {
 | 
			
		||||
  margin-top: 0 !important;
 | 
			
		||||
  padding-top: 0 !important;
 | 
			
		||||
}
 | 
			
		||||
a {
 | 
			
		||||
  color: #9f0;
 | 
			
		||||
  text-decoration: none;
 | 
			
		||||
}
 | 
			
		||||
a:hover {
 | 
			
		||||
  color: #74c100;
 | 
			
		||||
  text-decoration: underline;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
a.thumb {
 | 
			
		||||
  width: 128px;
 | 
			
		||||
  height: 128px;
 | 
			
		||||
  margin: 0 8px 8px 0;
 | 
			
		||||
  float: left;
 | 
			
		||||
  outline: none;
 | 
			
		||||
  background-size: cover;
 | 
			
		||||
  background-position: center center;
 | 
			
		||||
  box-shadow: inset 0 0 10px #4c4a4a;
 | 
			
		||||
}
 | 
			
		||||
a.thumb:hover {
 | 
			
		||||
  opacity: 0.5;
 | 
			
		||||
  box-shadow: inset 0 0 10px #9f0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div#page {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  margin: 0 auto;
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
  top: 22px;
 | 
			
		||||
  bottom: 16px;
 | 
			
		||||
}
 | 
			
		||||
div#thumbs {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  top: 0;
 | 
			
		||||
  left: 0;
 | 
			
		||||
  bottom: 0;
 | 
			
		||||
  right: 0;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
}
 | 
			
		||||
.navbar {
 | 
			
		||||
  margin: 0 auto;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  border: 0;
 | 
			
		||||
  padding-top: 0;
 | 
			
		||||
  padding-bottom: 0;
 | 
			
		||||
  font-weight: bold;
 | 
			
		||||
  position: fixed;
 | 
			
		||||
  overflow: visible;
 | 
			
		||||
  z-index: 999;
 | 
			
		||||
  background-color: #484747;
 | 
			
		||||
  border-bottom: 2px solid #9f0;
 | 
			
		||||
  text-align: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.pscroll {
 | 
			
		||||
  opacity: 0.7;
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  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: 3.2em;
 | 
			
		||||
}
 | 
			
		||||
div#down {
 | 
			
		||||
  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAANlBMVEUiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIjIyMiIiLm5uY3NzcqKipAQED///9KSkpHtWFIAAAACnRSTlMqACGx8/Cu6uerGsmyTAAAAM9JREFUeF7t1zkOwzAMBVEt3kLK2/0vm3KQivhWigTQ7+dBpZhyeW3+cNtSckqzd2xOafGu1TT1AVPyzv0YMIABDMD0fQB7u9S1HcCNXhAM4CAQZl98gZ8PgNsB3G69NwAEqQdAUHoABKUHQNB6AAStB0DQegAErQdA0HoABK0HQNB6AAShBwgE+gBACHuAWKCPAIS4B4gEegFAoHcFQKBXAAR6BUCgVwAEehlAoNcBt7Nd7TTXAYjD/uKDMYAB9B+etQ+o/cd3Lsv6NF9ryW9/v8EFMSsbFgAAAABJRU5ErkJggg==');
 | 
			
		||||
  bottom: 56px;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										25
									
								
								test2/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								test2/index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
<!doctype blah>
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
  <title>f0ckdev</title>
 | 
			
		||||
  <link rel="stylesheet" type="text/css" href="./style.css" />
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
  <div class="navbar">
 | 
			
		||||
    <span>Page 0</span>
 | 
			
		||||
    <a href="/">reload</a> | 
 | 
			
		||||
    <a href="#" data-id="1">page 1</a> | 
 | 
			
		||||
    <a href="#" data-id="2">page 2</a> | 
 | 
			
		||||
    <a href="#" data-id="3">page 3</a>
 | 
			
		||||
  </div>
 | 
			
		||||
  
 | 
			
		||||
  <div class="pscroll" id="up"></div>
 | 
			
		||||
  <div id="con"></div>
 | 
			
		||||
  <div class="pscroll" id="down"></div>
 | 
			
		||||
 | 
			
		||||
  <script src="//code.jquery.com/jquery-3.2.1.min.js"></script>
 | 
			
		||||
  <script src="./lib/jquery.ba-hashchange.js"></script>
 | 
			
		||||
  <script src="./lib/f0ck.js"></script>
 | 
			
		||||
  <script src="./script.js"></script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										13
									
								
								test2/lib/events.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								test2/lib/events.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
$(document).ready(() => {
 | 
			
		||||
  $(window).on("resize", () => f.render());
 | 
			
		||||
  $(window).bind('mousewheel DOMMouseScroll MozMousePixelScroll', event => {
 | 
			
		||||
  	f.page = (event.originalEvent.wheelDelta / 120 > 0)?-1:1;
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  $("div#up").on("click", () => {
 | 
			
		||||
  	f.page = -1;
 | 
			
		||||
  });
 | 
			
		||||
  $("div#down").on("click", () => {
 | 
			
		||||
  	f.page = 1;
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										178
									
								
								test2/lib/f0ck.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								test2/lib/f0ck.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,178 @@
 | 
			
		||||
class f0ck {
 | 
			
		||||
  constructor(hash = "") {
 | 
			
		||||
    this.debug();
 | 
			
		||||
    this.tpl = {
 | 
			
		||||
      row: ({ items }) => `<ul class="posts">${items}</ul>`,
 | 
			
		||||
      item: ({ id, title, stamp }) => `<li class="post"><a href="https://f0ck.me/${id}" title="${title} ; ${stamp}"><img class="thumb" src="https://f0ck.me/t/${id}.png" /></a></li>`,
 | 
			
		||||
    };
 | 
			
		||||
    this.numitems = this.sumItems();
 | 
			
		||||
    this.items = {
 | 
			
		||||
      items: [],
 | 
			
		||||
      last: null,
 | 
			
		||||
      first: null
 | 
			
		||||
    };
 | 
			
		||||
    this.tmphash = null;
 | 
			
		||||
    this.hash = hash;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  loadItems(init=false) {
 | 
			
		||||
    this.getItems().then(
 | 
			
		||||
      resolve => {
 | 
			
		||||
        console.log("resolved", this.items);
 | 
			
		||||
        //if(init) this.render(init);
 | 
			
		||||
      },
 | 
			
		||||
      reject => {
 | 
			
		||||
        console.error("REJECTED!");
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  getItems() {
 | 
			
		||||
    return new Promise((resolve, reject) => {
 | 
			
		||||
      $.getJSON(`${this.tmphash.link},${(this.numitems.ipp*2)}`, data => {
 | 
			
		||||
        console.log("received data", data);
 | 
			
		||||
        this.items.last = data.meta.last;
 | 
			
		||||
        this.items.first = data.meta.first;
 | 
			
		||||
        
 | 
			
		||||
        for(let item in data.items) {
 | 
			
		||||
          this.items.items[data.items[item].stamp] = data.items[item];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return resolve();
 | 
			
		||||
      }).fail(err => {
 | 
			
		||||
        return reject();
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  sumItems() {
 | 
			
		||||
    let h = $(window).innerHeight();
 | 
			
		||||
    let w = $(window).innerWidth();
 | 
			
		||||
    let itemsize = 128;
 | 
			
		||||
    let spacing = 10;
 | 
			
		||||
    let header = 90;
 | 
			
		||||
    let ipr = Math.floor( w / ( itemsize + spacing ) );
 | 
			
		||||
    let rpp = Math.floor( ( h - header ) / ( itemsize + spacing ) );
 | 
			
		||||
    let ipp = Math.floor( ipr * rpp );
 | 
			
		||||
    return {
 | 
			
		||||
      ipr: ipr, // items per row
 | 
			
		||||
      rpp: rpp, // rows per page
 | 
			
		||||
      ipp: ipp  // items per page
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  render(init=false) {
 | 
			
		||||
    let tmpnum = this.sumItems();
 | 
			
		||||
    let container = $("div#con");
 | 
			
		||||
    if(this.numitems.ipp !== tmpnum.ipp || init) {
 | 
			
		||||
      console.log("rendering from", this.current);
 | 
			
		||||
      if(typeof this.current !== "number")
 | 
			
		||||
        return;
 | 
			
		||||
      container.html("");
 | 
			
		||||
      this.numitems = tmpnum;
 | 
			
		||||
      let rowtpl = "";
 | 
			
		||||
      let j, tmplast = 0;
 | 
			
		||||
      for(var i = this.current+1; j < this.numitems.ipp; i--) {
 | 
			
		||||
        if(this.items[i]) {
 | 
			
		||||
          rowtpl += [{ id: this.items[i].id, title: this.items[i].mime, stamp: this.items[i].stamp }].map(this.tpl.item).join``;
 | 
			
		||||
          j++;
 | 
			
		||||
          tmplast = this.items[i].stamp;
 | 
			
		||||
        }
 | 
			
		||||
        if(this.items.length < i) {
 | 
			
		||||
          j = this.numitems.ipp;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      this.scope.last = tmplast;
 | 
			
		||||
      console.log("finished rendering", container.length);
 | 
			
		||||
      container.append( [{ items: rowtpl }].map(this.tpl.row).join`` );
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  set hash(val) {
 | 
			
		||||
    console.log("hash changed");
 | 
			
		||||
    let tmp = this.getlink(val);
 | 
			
		||||
    this.tmphash = tmp;
 | 
			
		||||
 | 
			
		||||
    //if(tmp.last < this.scope.first) {
 | 
			
		||||
      this.current = tmp.last;
 | 
			
		||||
      this.loadItems(true);
 | 
			
		||||
    //}
 | 
			
		||||
    //else if(tmp.last > this.scope.last || this.scope.last === 0) {
 | 
			
		||||
    //  this.current = tmp.last;
 | 
			
		||||
    //  this.loadItems(true);
 | 
			
		||||
    //}
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  gethash() {
 | 
			
		||||
    return this.tmphash;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  debug() {
 | 
			
		||||
    $(".navbar a").on("click", event => {
 | 
			
		||||
      switch(event.target.innerText) {
 | 
			
		||||
        case "page 1":
 | 
			
		||||
          this.currentpage = 0;
 | 
			
		||||
          this.render(true);
 | 
			
		||||
        break;
 | 
			
		||||
        case "page 2":
 | 
			
		||||
          this.currentpage = 1;
 | 
			
		||||
          this.render(true);
 | 
			
		||||
        break;
 | 
			
		||||
        case "page 3":
 | 
			
		||||
          this.currentpage = 2;
 | 
			
		||||
          this.render(true);
 | 
			
		||||
        break;
 | 
			
		||||
        default:
 | 
			
		||||
          console.log("nope");
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      $(".navbar span").html(`Page ${this.currentpage}`);
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  getlink(tmp) {
 | 
			
		||||
    const tpl = {
 | 
			
		||||
      user: ({ user, mime, last, eps }) => `user,${user},${mime},${last}`,
 | 
			
		||||
      mime: ({ user, mime, last, eps }) => `mime,${mime},${user},${last}`,
 | 
			
		||||
      new: ({ user, mime, last, eps }) => `items,${last}`,
 | 
			
		||||
    };
 | 
			
		||||
    let blah = {
 | 
			
		||||
      mode: "",
 | 
			
		||||
      user: "",
 | 
			
		||||
      mime: "",
 | 
			
		||||
      last: 0,
 | 
			
		||||
      post: 0
 | 
			
		||||
    };
 | 
			
		||||
    let api = "/api/?";
 | 
			
		||||
 | 
			
		||||
    if(!tmp.match(/\//)) {
 | 
			
		||||
      tmp = "#new/";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    tmp = (tmp.match(/,/)?tmp:`${tmp},`).substr(1).split(",");
 | 
			
		||||
    console.log(tmp);
 | 
			
		||||
    const args = {
 | 
			
		||||
      l: tmp[0].split("/"),
 | 
			
		||||
      r: tmp[1].split("/")
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    blah.mode = ( args.l[0].length === 0 )? "new" : args.l[0];
 | 
			
		||||
    blah.last = parseInt(args.r[0]) || 0;
 | 
			
		||||
    blah.post = parseInt(args.r[1]) || 0;
 | 
			
		||||
    switch(blah.mode) {
 | 
			
		||||
      case "user":
 | 
			
		||||
        blah.user = ( args.l[1].length === 0 )? "" : args.l[1];
 | 
			
		||||
        blah.mime = ( args.l[2].length === 0 )? "" : args.l[2];
 | 
			
		||||
      break;
 | 
			
		||||
      case "mime":
 | 
			
		||||
        blah.user = ( args.l[2].length === 0 )? "" : args.l[2];
 | 
			
		||||
        blah.mime = ( args.l[1].length === 0 )? "" : args.l[1];
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    return {
 | 
			
		||||
      link: api + [{ user: blah.user, mime: blah.mime, last: blah.last, eps: this.numitems.ipp }].map(tpl[blah.mode]).join``,
 | 
			
		||||
      args: blah
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										299
									
								
								test2/lib/jquery.ba-hashchange.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										299
									
								
								test2/lib/jquery.ba-hashchange.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,299 @@
 | 
			
		||||
/*!
 | 
			
		||||
 * jQuery hashchange event - v1.3 - 7/21/2010
 | 
			
		||||
 * http://benalman.com/projects/jquery-hashchange-plugin/
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (c) 2010 "Cowboy" Ben Alman
 | 
			
		||||
 * Dual licensed under the MIT and GPL licenses.
 | 
			
		||||
 * http://benalman.com/about/license/
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
// Script: jQuery hashchange event
 | 
			
		||||
//
 | 
			
		||||
// *Version: 1.3, Last updated: 7/21/2010*
 | 
			
		||||
// 
 | 
			
		||||
// Project Home - http://benalman.com/projects/jquery-hashchange-plugin/
 | 
			
		||||
// GitHub       - http://github.com/cowboy/jquery-hashchange/
 | 
			
		||||
// Source       - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.js
 | 
			
		||||
// (Minified)   - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.min.js (0.8kb gzipped)
 | 
			
		||||
// 
 | 
			
		||||
// About: License
 | 
			
		||||
// 
 | 
			
		||||
// Copyright (c) 2010 "Cowboy" Ben Alman,
 | 
			
		||||
// Dual licensed under the MIT and GPL licenses.
 | 
			
		||||
// http://benalman.com/about/license/
 | 
			
		||||
// 
 | 
			
		||||
// About: Examples
 | 
			
		||||
// 
 | 
			
		||||
// These working examples, complete with fully commented code, illustrate a few
 | 
			
		||||
// ways in which this plugin can be used.
 | 
			
		||||
// 
 | 
			
		||||
// hashchange event - http://benalman.com/code/projects/jquery-hashchange/examples/hashchange/
 | 
			
		||||
// document.domain - http://benalman.com/code/projects/jquery-hashchange/examples/document_domain/
 | 
			
		||||
// 
 | 
			
		||||
// About: Support and Testing
 | 
			
		||||
// 
 | 
			
		||||
// Information about what version or versions of jQuery this plugin has been
 | 
			
		||||
// tested with, what browsers it has been tested in, and where the unit tests
 | 
			
		||||
// reside (so you can test it yourself).
 | 
			
		||||
// 
 | 
			
		||||
// jQuery Versions - 1.2.6, 1.3.2, 1.4.1, 1.4.2
 | 
			
		||||
// Browsers Tested - Internet Explorer 6-8, Firefox 2-4, Chrome 5-6, Safari 3.2-5,
 | 
			
		||||
//                   Opera 9.6-10.60, iPhone 3.1, Android 1.6-2.2, BlackBerry 4.6-5.
 | 
			
		||||
// Unit Tests      - http://benalman.com/code/projects/jquery-hashchange/unit/
 | 
			
		||||
// 
 | 
			
		||||
// About: Known issues
 | 
			
		||||
// 
 | 
			
		||||
// While this jQuery hashchange event implementation is quite stable and
 | 
			
		||||
// robust, there are a few unfortunate browser bugs surrounding expected
 | 
			
		||||
// hashchange event-based behaviors, independent of any JavaScript
 | 
			
		||||
// window.onhashchange abstraction. See the following examples for more
 | 
			
		||||
// information:
 | 
			
		||||
// 
 | 
			
		||||
// Chrome: Back Button - http://benalman.com/code/projects/jquery-hashchange/examples/bug-chrome-back-button/
 | 
			
		||||
// Firefox: Remote XMLHttpRequest - http://benalman.com/code/projects/jquery-hashchange/examples/bug-firefox-remote-xhr/
 | 
			
		||||
// WebKit: Back Button in an Iframe - http://benalman.com/code/projects/jquery-hashchange/examples/bug-webkit-hash-iframe/
 | 
			
		||||
// Safari: Back Button from a different domain - http://benalman.com/code/projects/jquery-hashchange/examples/bug-safari-back-from-diff-domain/
 | 
			
		||||
// 
 | 
			
		||||
// Also note that should a browser natively support the window.onhashchange 
 | 
			
		||||
// event, but not report that it does, the fallback polling loop will be used.
 | 
			
		||||
// 
 | 
			
		||||
// About: Release History
 | 
			
		||||
// 
 | 
			
		||||
// 1.3   - (7/21/2010) Reorganized IE6/7 Iframe code to make it more
 | 
			
		||||
//         "removable" for mobile-only development. Added IE6/7 document.title
 | 
			
		||||
//         support. Attempted to make Iframe as hidden as possible by using
 | 
			
		||||
//         techniques from http://www.paciellogroup.com/blog/?p=604. Added 
 | 
			
		||||
//         support for the "shortcut" format $(window).hashchange( fn ) and
 | 
			
		||||
//         $(window).hashchange() like jQuery provides for built-in events.
 | 
			
		||||
//         Renamed jQuery.hashchangeDelay to <jQuery.fn.hashchange.delay> and
 | 
			
		||||
//         lowered its default value to 50. Added <jQuery.fn.hashchange.domain>
 | 
			
		||||
//         and <jQuery.fn.hashchange.src> properties plus document-domain.html
 | 
			
		||||
//         file to address access denied issues when setting document.domain in
 | 
			
		||||
//         IE6/7.
 | 
			
		||||
// 1.2   - (2/11/2010) Fixed a bug where coming back to a page using this plugin
 | 
			
		||||
//         from a page on another domain would cause an error in Safari 4. Also,
 | 
			
		||||
//         IE6/7 Iframe is now inserted after the body (this actually works),
 | 
			
		||||
//         which prevents the page from scrolling when the event is first bound.
 | 
			
		||||
//         Event can also now be bound before DOM ready, but it won't be usable
 | 
			
		||||
//         before then in IE6/7.
 | 
			
		||||
// 1.1   - (1/21/2010) Incorporated document.documentMode test to fix IE8 bug
 | 
			
		||||
//         where browser version is incorrectly reported as 8.0, despite
 | 
			
		||||
//         inclusion of the X-UA-Compatible IE=EmulateIE7 meta tag.
 | 
			
		||||
// 1.0   - (1/9/2010) Initial Release. Broke out the jQuery BBQ event.special
 | 
			
		||||
//         window.onhashchange functionality into a separate plugin for users
 | 
			
		||||
//         who want just the basic event & back button support, without all the
 | 
			
		||||
//         extra awesomeness that BBQ provides. This plugin will be included as
 | 
			
		||||
//         part of jQuery BBQ, but also be available separately.
 | 
			
		||||
 | 
			
		||||
(function($,window,undefined){
 | 
			
		||||
  '$:nomunge'; // Used by YUI compressor.
 | 
			
		||||
  
 | 
			
		||||
  // Reused string.
 | 
			
		||||
  var str_hashchange = 'hashchange',
 | 
			
		||||
    
 | 
			
		||||
    // Method / object references.
 | 
			
		||||
    doc = document,
 | 
			
		||||
    fake_onhashchange,
 | 
			
		||||
    special = $.event.special,
 | 
			
		||||
    
 | 
			
		||||
    // Does the browser support window.onhashchange? Note that IE8 running in
 | 
			
		||||
    // IE7 compatibility mode reports true for 'onhashchange' in window, even
 | 
			
		||||
    // though the event isn't supported, so also test document.documentMode.
 | 
			
		||||
    doc_mode = doc.documentMode,
 | 
			
		||||
    supports_onhashchange = 'on' + str_hashchange in window && ( doc_mode === undefined || doc_mode > 7 );
 | 
			
		||||
  
 | 
			
		||||
  // Get location.hash (or what you'd expect location.hash to be) sans any
 | 
			
		||||
  // leading #. Thanks for making this necessary, Firefox!
 | 
			
		||||
  function get_fragment( url ) {
 | 
			
		||||
    url = url || location.href;
 | 
			
		||||
    return '#' + url.replace( /^[^#]*#?(.*)$/, '$1' );
 | 
			
		||||
  };
 | 
			
		||||
  
 | 
			
		||||
  // Method: jQuery.fn.hashchange
 | 
			
		||||
  // 
 | 
			
		||||
  // Bind a handler to the window.onhashchange event or trigger all bound
 | 
			
		||||
  // window.onhashchange event handlers. This behavior is consistent with
 | 
			
		||||
  // jQuery's built-in event handlers.
 | 
			
		||||
  // 
 | 
			
		||||
  // Usage:
 | 
			
		||||
  // 
 | 
			
		||||
  // > jQuery(window).hashchange( [ handler ] );
 | 
			
		||||
  // 
 | 
			
		||||
  // Arguments:
 | 
			
		||||
  // 
 | 
			
		||||
  //  handler - (Function) Optional handler to be bound to the hashchange
 | 
			
		||||
  //    event. This is a "shortcut" for the more verbose form:
 | 
			
		||||
  //    jQuery(window).bind( 'hashchange', handler ). If handler is omitted,
 | 
			
		||||
  //    all bound window.onhashchange event handlers will be triggered. This
 | 
			
		||||
  //    is a shortcut for the more verbose
 | 
			
		||||
  //    jQuery(window).trigger( 'hashchange' ). These forms are described in
 | 
			
		||||
  //    the <hashchange event> section.
 | 
			
		||||
  // 
 | 
			
		||||
  // Returns:
 | 
			
		||||
  // 
 | 
			
		||||
  //  (jQuery) The initial jQuery collection of elements.
 | 
			
		||||
  
 | 
			
		||||
  // Allow the "shortcut" format $(elem).hashchange( fn ) for binding and
 | 
			
		||||
  // $(elem).hashchange() for triggering, like jQuery does for built-in events.
 | 
			
		||||
  $.fn[ str_hashchange ] = function( fn ) {
 | 
			
		||||
    return fn ? this.bind( str_hashchange, fn ) : this.trigger( str_hashchange );
 | 
			
		||||
  };
 | 
			
		||||
  
 | 
			
		||||
  // Property: jQuery.fn.hashchange.delay
 | 
			
		||||
  // 
 | 
			
		||||
  // The numeric interval (in milliseconds) at which the <hashchange event>
 | 
			
		||||
  // polling loop executes. Defaults to 50.
 | 
			
		||||
  
 | 
			
		||||
  // Property: jQuery.fn.hashchange.domain
 | 
			
		||||
  // 
 | 
			
		||||
  // If you're setting document.domain in your JavaScript, and you want hash
 | 
			
		||||
  // history to work in IE6/7, not only must this property be set, but you must
 | 
			
		||||
  // also set document.domain BEFORE jQuery is loaded into the page. This
 | 
			
		||||
  // property is only applicable if you are supporting IE6/7 (or IE8 operating
 | 
			
		||||
  // in "IE7 compatibility" mode).
 | 
			
		||||
  // 
 | 
			
		||||
  // In addition, the <jQuery.fn.hashchange.src> property must be set to the
 | 
			
		||||
  // path of the included "document-domain.html" file, which can be renamed or
 | 
			
		||||
  // modified if necessary (note that the document.domain specified must be the
 | 
			
		||||
  // same in both your main JavaScript as well as in this file).
 | 
			
		||||
  // 
 | 
			
		||||
  // Usage:
 | 
			
		||||
  // 
 | 
			
		||||
  // jQuery.fn.hashchange.domain = document.domain;
 | 
			
		||||
  
 | 
			
		||||
  // Property: jQuery.fn.hashchange.src
 | 
			
		||||
  // 
 | 
			
		||||
  // If, for some reason, you need to specify an Iframe src file (for example,
 | 
			
		||||
  // when setting document.domain as in <jQuery.fn.hashchange.domain>), you can
 | 
			
		||||
  // do so using this property. Note that when using this property, history
 | 
			
		||||
  // won't be recorded in IE6/7 until the Iframe src file loads. This property
 | 
			
		||||
  // is only applicable if you are supporting IE6/7 (or IE8 operating in "IE7
 | 
			
		||||
  // compatibility" mode).
 | 
			
		||||
  // 
 | 
			
		||||
  // Usage:
 | 
			
		||||
  // 
 | 
			
		||||
  // jQuery.fn.hashchange.src = 'path/to/file.html';
 | 
			
		||||
  
 | 
			
		||||
  $.fn[ str_hashchange ].delay = 50;
 | 
			
		||||
  /*
 | 
			
		||||
  $.fn[ str_hashchange ].domain = null;
 | 
			
		||||
  $.fn[ str_hashchange ].src = null;
 | 
			
		||||
  */
 | 
			
		||||
  
 | 
			
		||||
  // Event: hashchange event
 | 
			
		||||
  // 
 | 
			
		||||
  // Fired when location.hash changes. In browsers that support it, the native
 | 
			
		||||
  // HTML5 window.onhashchange event is used, otherwise a polling loop is
 | 
			
		||||
  // initialized, running every <jQuery.fn.hashchange.delay> milliseconds to
 | 
			
		||||
  // see if the hash has changed. In IE6/7 (and IE8 operating in "IE7
 | 
			
		||||
  // compatibility" mode), a hidden Iframe is created to allow the back button
 | 
			
		||||
  // and hash-based history to work.
 | 
			
		||||
  // 
 | 
			
		||||
  // Usage as described in <jQuery.fn.hashchange>:
 | 
			
		||||
  // 
 | 
			
		||||
  // > // Bind an event handler.
 | 
			
		||||
  // > jQuery(window).hashchange( function(e) {
 | 
			
		||||
  // >   var hash = location.hash;
 | 
			
		||||
  // >   ...
 | 
			
		||||
  // > });
 | 
			
		||||
  // > 
 | 
			
		||||
  // > // Manually trigger the event handler.
 | 
			
		||||
  // > jQuery(window).hashchange();
 | 
			
		||||
  // 
 | 
			
		||||
  // A more verbose usage that allows for event namespacing:
 | 
			
		||||
  // 
 | 
			
		||||
  // > // Bind an event handler.
 | 
			
		||||
  // > jQuery(window).bind( 'hashchange', function(e) {
 | 
			
		||||
  // >   var hash = location.hash;
 | 
			
		||||
  // >   ...
 | 
			
		||||
  // > });
 | 
			
		||||
  // > 
 | 
			
		||||
  // > // Manually trigger the event handler.
 | 
			
		||||
  // > jQuery(window).trigger( 'hashchange' );
 | 
			
		||||
  // 
 | 
			
		||||
  // Additional Notes:
 | 
			
		||||
  // 
 | 
			
		||||
  // * The polling loop and Iframe are not created until at least one handler
 | 
			
		||||
  //   is actually bound to the 'hashchange' event.
 | 
			
		||||
  // * If you need the bound handler(s) to execute immediately, in cases where
 | 
			
		||||
  //   a location.hash exists on page load, via bookmark or page refresh for
 | 
			
		||||
  //   example, use jQuery(window).hashchange() or the more verbose 
 | 
			
		||||
  //   jQuery(window).trigger( 'hashchange' ).
 | 
			
		||||
  // * The event can be bound before DOM ready, but since it won't be usable
 | 
			
		||||
  //   before then in IE6/7 (due to the necessary Iframe), recommended usage is
 | 
			
		||||
  //   to bind it inside a DOM ready handler.
 | 
			
		||||
  
 | 
			
		||||
  // Override existing $.event.special.hashchange methods (allowing this plugin
 | 
			
		||||
  // to be defined after jQuery BBQ in BBQ's source code).
 | 
			
		||||
  special[ str_hashchange ] = $.extend( special[ str_hashchange ], {
 | 
			
		||||
    
 | 
			
		||||
    // Called only when the first 'hashchange' event is bound to window.
 | 
			
		||||
    setup: function() {
 | 
			
		||||
      // If window.onhashchange is supported natively, there's nothing to do..
 | 
			
		||||
      if ( supports_onhashchange ) { return false; }
 | 
			
		||||
      
 | 
			
		||||
      // Otherwise, we need to create our own. And we don't want to call this
 | 
			
		||||
      // until the user binds to the event, just in case they never do, since it
 | 
			
		||||
      // will create a polling loop and possibly even a hidden Iframe.
 | 
			
		||||
      $( fake_onhashchange.start );
 | 
			
		||||
    },
 | 
			
		||||
    
 | 
			
		||||
    // Called only when the last 'hashchange' event is unbound from window.
 | 
			
		||||
    teardown: function() {
 | 
			
		||||
      // If window.onhashchange is supported natively, there's nothing to do..
 | 
			
		||||
      if ( supports_onhashchange ) { return false; }
 | 
			
		||||
      
 | 
			
		||||
      // Otherwise, we need to stop ours (if possible).
 | 
			
		||||
      $( fake_onhashchange.stop );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
  });
 | 
			
		||||
  
 | 
			
		||||
  // fake_onhashchange does all the work of triggering the window.onhashchange
 | 
			
		||||
  // event for browsers that don't natively support it, including creating a
 | 
			
		||||
  // polling loop to watch for hash changes and in IE 6/7 creating a hidden
 | 
			
		||||
  // Iframe to enable back and forward.
 | 
			
		||||
  fake_onhashchange = (function(){
 | 
			
		||||
    var self = {},
 | 
			
		||||
      timeout_id,
 | 
			
		||||
      
 | 
			
		||||
      // Remember the initial hash so it doesn't get triggered immediately.
 | 
			
		||||
      last_hash = get_fragment(),
 | 
			
		||||
      
 | 
			
		||||
      fn_retval = function(val){ return val; },
 | 
			
		||||
      history_set = fn_retval,
 | 
			
		||||
      history_get = fn_retval;
 | 
			
		||||
    
 | 
			
		||||
    // Start the polling loop.
 | 
			
		||||
    self.start = function() {
 | 
			
		||||
      timeout_id || poll();
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    // Stop the polling loop.
 | 
			
		||||
    self.stop = function() {
 | 
			
		||||
      timeout_id && clearTimeout( timeout_id );
 | 
			
		||||
      timeout_id = undefined;
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    // This polling loop checks every $.fn.hashchange.delay milliseconds to see
 | 
			
		||||
    // if location.hash has changed, and triggers the 'hashchange' event on
 | 
			
		||||
    // window when necessary.
 | 
			
		||||
    function poll() {
 | 
			
		||||
      var hash = get_fragment(),
 | 
			
		||||
        history_hash = history_get( last_hash );
 | 
			
		||||
      
 | 
			
		||||
      if ( hash !== last_hash ) {
 | 
			
		||||
        history_set( last_hash = hash, history_hash );
 | 
			
		||||
        
 | 
			
		||||
        $(window).trigger( str_hashchange );
 | 
			
		||||
        
 | 
			
		||||
      } else if ( history_hash !== last_hash ) {
 | 
			
		||||
        location.href = location.href.replace( /#.*/, '' ) + history_hash;
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      timeout_id = setTimeout( poll, $.fn[ str_hashchange ].delay );
 | 
			
		||||
    };
 | 
			
		||||
    return self;
 | 
			
		||||
  })();
 | 
			
		||||
  
 | 
			
		||||
})(jQuery,this);
 | 
			
		||||
							
								
								
									
										35
									
								
								test2/lib/lib.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								test2/lib/lib.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
var getlink = tmp => {
 | 
			
		||||
  const tpl = {
 | 
			
		||||
    user: ({ user, mime, last, eps }) => `user,${user},${mime},${last},${eps}`,
 | 
			
		||||
    mime: ({ user, mime, last, eps }) => `mime,${mime},${user},${last},${eps}`,
 | 
			
		||||
    new: ({ user, mime, last, eps }) => `items,${last},${eps}`,
 | 
			
		||||
  };
 | 
			
		||||
  
 | 
			
		||||
  let api = "/api/?";
 | 
			
		||||
  tmp = (tmp.match(/,/)?tmp:`${tmp},`).substr(1).split(",");
 | 
			
		||||
  const args = {
 | 
			
		||||
    l: tmp[0].split("/"),
 | 
			
		||||
    r: tmp[1].split("/")
 | 
			
		||||
  };
 | 
			
		||||
  tmp = {
 | 
			
		||||
    mode: "",
 | 
			
		||||
    user: "",
 | 
			
		||||
    mime: "",
 | 
			
		||||
    last: 0,
 | 
			
		||||
    post: 0
 | 
			
		||||
  };
 | 
			
		||||
  tmp.mode = ( args.l[0].length === 0 )? "new" : args.l[0];
 | 
			
		||||
  tmp.last = parseInt(args.r[0]) || 0;
 | 
			
		||||
  tmp.post = parseInt(args.r[1]) || 0;
 | 
			
		||||
  switch(tmp.mode) {
 | 
			
		||||
    case "user":
 | 
			
		||||
      tmp.user = ( args.l[1].length === 0 )? "" : args.l[1];
 | 
			
		||||
      tmp.mime = ( args.l[2].length === 0 )? "" : args.l[2];
 | 
			
		||||
    break;
 | 
			
		||||
    case "mime":
 | 
			
		||||
      tmp.user = ( args.l[2].length === 0 )? "" : args.l[2];
 | 
			
		||||
      tmp.mime = ( args.l[1].length === 0 )? "" : args.l[1];
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
  return api + [{ user: tmp.user, mime: tmp.mime, last: tmp.last, eps: 3 }].map(tpl[tmp.mode]).join``;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										38
									
								
								test2/script.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								test2/script.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
$(document).ready(() => {
 | 
			
		||||
  var f = new f0ck(window.location.hash);
 | 
			
		||||
  
 | 
			
		||||
  $(window).hashchange(() => {
 | 
			
		||||
    f.hash = window.location.hash;
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  //$(window).on("resize", () => f.render());
 | 
			
		||||
  //$(window).bind('mousewheel DOMMouseScroll MozMousePixelScroll', event => {
 | 
			
		||||
  //  f.page = (event.originalEvent.wheelDelta / 120 > 0)?-1:1;
 | 
			
		||||
  //});
 | 
			
		||||
 | 
			
		||||
  $("div#up").on("click", () => {
 | 
			
		||||
    return;
 | 
			
		||||
  });
 | 
			
		||||
  $("div#down").on("click", () => {
 | 
			
		||||
    let hash = f.tmphash.args;
 | 
			
		||||
 | 
			
		||||
    let tmp = hash.mode;
 | 
			
		||||
    switch(hash.mode) {
 | 
			
		||||
      case "user":
 | 
			
		||||
        tmp += (hash.user.length > 1)?`/${hash.user}`:"";
 | 
			
		||||
        tmp += (hash.mime.length > 1)?`/${hash.mime}`:"";
 | 
			
		||||
      break;
 | 
			
		||||
      case "mime":
 | 
			
		||||
        tmp += (hash.mime.length > 1)?`/${hash.mime}`:"";
 | 
			
		||||
        tmp += (hash.user.length > 1)?`/${hash.user}`:"";
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    tmp += ",";
 | 
			
		||||
    tmp += `${f.scope.last}`;
 | 
			
		||||
    //tmp += `${f.pages[f.currentpage][f.pages[f.currentpage].length-1][f.pages[f.currentpage][f.pages[f.currentpage].length-1].length-1].stamp}`;
 | 
			
		||||
 | 
			
		||||
    window.location.hash = tmp;
 | 
			
		||||
    f.hash = window.location.hash;
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										81
									
								
								test2/style.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								test2/style.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
			
		||||
* {
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
body {
 | 
			
		||||
  margin: 0em auto 3em auto;
 | 
			
		||||
  background-color: #262626;
 | 
			
		||||
  color: #fff;
 | 
			
		||||
  font-family: Monospace;
 | 
			
		||||
  font-size: 12px;
 | 
			
		||||
  line-height: 1.42857143;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
html, body {
 | 
			
		||||
  max-height: 100%;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
a {
 | 
			
		||||
  color: #9f0;
 | 
			
		||||
  text-decoration: none;
 | 
			
		||||
}
 | 
			
		||||
a:hover {
 | 
			
		||||
  color: #74c100;
 | 
			
		||||
  text-decoration: underline;
 | 
			
		||||
}
 | 
			
		||||
div#con {
 | 
			
		||||
  padding-top: 2.2em;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
}
 | 
			
		||||
ul {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  margin: 15px 0 15px 0;
 | 
			
		||||
}
 | 
			
		||||
li.post {
 | 
			
		||||
  margin: 0 5px 0 5px;
 | 
			
		||||
  height: 128px;
 | 
			
		||||
  width: 128px;
 | 
			
		||||
  display: inline;
 | 
			
		||||
}
 | 
			
		||||
.thumb {
 | 
			
		||||
  border: 2px solid #4c4a4a;
 | 
			
		||||
  height: 128px;
 | 
			
		||||
  width: 128px;
 | 
			
		||||
}
 | 
			
		||||
.thumb:hover {
 | 
			
		||||
	opacity: 0.7;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.navbar {
 | 
			
		||||
  margin: 0 auto;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  border: 0;
 | 
			
		||||
  padding-top: 0;
 | 
			
		||||
  padding-bottom: 0;
 | 
			
		||||
  font-weight: bold;
 | 
			
		||||
  position: fixed;
 | 
			
		||||
  overflow: visible;
 | 
			
		||||
  z-index: 999;
 | 
			
		||||
  background-color: #484747;
 | 
			
		||||
  border-bottom: 2px solid #9f0;
 | 
			
		||||
  text-align: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div#up {
 | 
			
		||||
  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAANlBMVEUiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIjIyP///8iIiLm5uY3NzdKSkpAQEAqKipZf6aEAAAACnRSTlOxIfAAKvPn6quuQpaxIgAAAMZJREFUeF7t17uOwjAYROHjOMCuL0l4/5ddbQU0M4p/RIE8/flkyY1NTr/XNrjrT8qsSwtsWaGFBpcYcKEF9xFgAhMo9xIBytFrP8owUPb6v10JmN4K6N4L6N4L6N4L6N4L6N4L6N4L6N4L6N4L6N4L6N4L6N4L6N4L6N4L6N4L6N4L6N4L6N4L6N4L6N4L6N4LiN4LD2Cv53c8AaUPAL08AXVk9zeeoG3nhb69XuP5fdkLZQITmED840kMIP75zonbaH4j5T8NALtW477R3QAAAABJRU5ErkJggg==');
 | 
			
		||||
  top: 3.2em;
 | 
			
		||||
}
 | 
			
		||||
div#down {
 | 
			
		||||
  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAANlBMVEUiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIjIyMiIiLm5uY3NzcqKipAQED///9KSkpHtWFIAAAACnRSTlMqACGx8/Cu6uerGsmyTAAAAM9JREFUeF7t1zkOwzAMBVEt3kLK2/0vm3KQivhWigTQ7+dBpZhyeW3+cNtSckqzd2xOafGu1TT1AVPyzv0YMIABDMD0fQB7u9S1HcCNXhAM4CAQZl98gZ8PgNsB3G69NwAEqQdAUHoABKUHQNB6AAStB0DQegAErQdA0HoABK0HQNB6AAShBwgE+gBACHuAWKCPAIS4B4gEegFAoHcFQKBXAAR6BUCgVwAEehlAoNcBt7Nd7TTXAYjD/uKDMYAB9B+etQ+o/cd3Lsv6NF9ryW9/v8EFMSsbFgAAAABJRU5ErkJggg==');
 | 
			
		||||
  bottom: 56px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.pscroll {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  height: 64px;
 | 
			
		||||
  width: 64px;
 | 
			
		||||
  left: 50%;
 | 
			
		||||
  margin-left: -36px;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										13
									
								
								test3/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								test3/index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
  <link href="./style.css" rel="stylesheet" />
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
  <div class="navbar"> </div>
 | 
			
		||||
  <div id="page">
 | 
			
		||||
    <div id="thumbs" style="top: 0;">
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
  <script src="./script.js"></script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										37
									
								
								test3/promises_fetch.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								test3/promises_fetch.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
/*let rt = {
 | 
			
		||||
  user: "Flummi",
 | 
			
		||||
  mime: "",
 | 
			
		||||
  stamp: 1506717559,
 | 
			
		||||
  eps: 20,
 | 
			
		||||
  act: 0,
 | 
			
		||||
  items: new Map(),
 | 
			
		||||
  last: 0,
 | 
			
		||||
  first: 0,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
(function getitems() {
 | 
			
		||||
  Promise.all([
 | 
			
		||||
    fetch(`/api/test/?user=${rt.user}&mime=${rt.mime}&stamp=${rt.stamp}&eps=${rt.eps}`),
 | 
			
		||||
    fetch(`/api/test/?user=${rt.user}&mime=${rt.mime}&stamp=${rt.stamp}&eps=${rt.eps}&get=meta`)
 | 
			
		||||
  ])
 | 
			
		||||
  .then(res => Promise.all(res.map(muh => muh.json())))
 | 
			
		||||
  .then(data => {
 | 
			
		||||
    return {
 | 
			
		||||
      act: data[0].items[0][0],
 | 
			
		||||
      items: data[0].items[1].concat(data[0].items[0]),
 | 
			
		||||
      items: [...data[0].items[1], ...data[0].items[0]],
 | 
			
		||||
      meta: data[1].meta
 | 
			
		||||
    };
 | 
			
		||||
  })
 | 
			
		||||
  .then(final => render(final));
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
function render(data=null) {
 | 
			
		||||
  if(data !== null) {
 | 
			
		||||
    data.items.forEach(e => rt.items.set(e.stamp, e));
 | 
			
		||||
    rt.act = data.act.stamp;
 | 
			
		||||
    rt.last = data.meta.last;
 | 
			
		||||
    rt.first = data.meta.first;
 | 
			
		||||
  }
 | 
			
		||||
  console.log(rt);
 | 
			
		||||
}*/
 | 
			
		||||
							
								
								
									
										120
									
								
								test3/script.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								test3/script.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,120 @@
 | 
			
		||||
let _layout = {
 | 
			
		||||
  items: {
 | 
			
		||||
    size: 128,
 | 
			
		||||
    gutter: 8
 | 
			
		||||
  },
 | 
			
		||||
  min_margin: 16,
 | 
			
		||||
  min_rows: 2,
 | 
			
		||||
  min_cols: 3
 | 
			
		||||
};
 | 
			
		||||
_tpl = {
 | 
			
		||||
  row: ({ rowid, items }) => `<div class="row" data-row="${rowid}">${items}</div>`,
 | 
			
		||||
  item: ({ id, }) => `<a href="//f0ck.me/${id}" class="thumb" style="background-image:url('//f0ck.me/t/${id}.png')"></a>`,
 | 
			
		||||
};
 | 
			
		||||
let rt = {
 | 
			
		||||
  user: "Flummi",
 | 
			
		||||
  mime: "",
 | 
			
		||||
  stamp: 1506717559,
 | 
			
		||||
  act: 0,
 | 
			
		||||
  items: new Map(),
 | 
			
		||||
  last: 0,
 | 
			
		||||
  first: 0,
 | 
			
		||||
};
 | 
			
		||||
let _cache = [];
 | 
			
		||||
let _dims = null;
 | 
			
		||||
let _scroll = false;
 | 
			
		||||
let _scrollrows = 4;
 | 
			
		||||
let _container = {
 | 
			
		||||
  debug: document.querySelector("div.navbar"),
 | 
			
		||||
  page: document.querySelector("div#page"),
 | 
			
		||||
  thumbs: document.querySelector("div#thumbs")
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
window.onload = () => {
 | 
			
		||||
  function resize() {
 | 
			
		||||
    let rows = Math.max(~~((window.innerHeight - _layout.min_margin + _layout.items.size) / (_layout.items.size + _layout.items.gutter)), _layout.min_rows);
 | 
			
		||||
    let cols = Math.max(~~((window.innerWidth - _layout.min_margin) / (_layout.items.size + _layout.items.gutter)), _layout.min_cols);
 | 
			
		||||
    let pageWidth = cols * (_layout.items.size + _layout.items.gutter);
 | 
			
		||||
    let margin = Math.max((window.innerWidth - pageWidth + _layout.items.gutter) / _layout.min_rows, 0);
 | 
			
		||||
    let page = _container.page;
 | 
			
		||||
    page.style.width = pageWidth;
 | 
			
		||||
    page.style.marginLeft = margin;
 | 
			
		||||
    _dims = {
 | 
			
		||||
      rows: rows,
 | 
			
		||||
      cols: cols,
 | 
			
		||||
      eps: rows * cols,
 | 
			
		||||
      pageWidth: pageWidth,
 | 
			
		||||
      margin: margin
 | 
			
		||||
    };
 | 
			
		||||
    render();
 | 
			
		||||
  }
 | 
			
		||||
  function scroll(e) {
 | 
			
		||||
    if(e.preventDefault)
 | 
			
		||||
      e.preventDefault();
 | 
			
		||||
    let deltaY = e.deltaY < 0?-1:1; // - up, + down
 | 
			
		||||
 | 
			
		||||
    if(!_scroll) {
 | 
			
		||||
      _scroll = true;
 | 
			
		||||
      let dura = 500;
 | 
			
		||||
      let top = parseInt(_container.thumbs.style.top.replace("px",""));
 | 
			
		||||
      let go = `${(top + (-deltaY * ((_layout.items.size + _layout.items.gutter) * _scrollrows)))}`;
 | 
			
		||||
      _container.thumbs.animate( [{ top: `${top}px` }, { top: `${go}px` } ], { duration: dura } );
 | 
			
		||||
      setTimeout(() => { // after scroll
 | 
			
		||||
        _container.thumbs.style.top = `${go}px`;
 | 
			
		||||
        _scroll = false;
 | 
			
		||||
        //console.log( getpos( thumbs.querySelectorAll("div.row") ) );
 | 
			
		||||
        console.log( getposall( thumbs.querySelectorAll("div.row") ) );
 | 
			
		||||
      }, dura);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  resize();
 | 
			
		||||
  window.addEventListener("resize", resize);
 | 
			
		||||
  document.addEventListener("wheel", scroll);
 | 
			
		||||
 | 
			
		||||
  function render() {
 | 
			
		||||
    let items = new Array(_dims.eps).fill({id: 25788}, 0, _dims.eps);
 | 
			
		||||
    let rowtpl = "";
 | 
			
		||||
    let blah = "";
 | 
			
		||||
    let rowid = 0;
 | 
			
		||||
    let j = 0;
 | 
			
		||||
    items.forEach(e => {
 | 
			
		||||
      rowtpl += [{ id: e.id }].map(_tpl.item).join``;
 | 
			
		||||
      if(++j % _dims.cols === 0) {
 | 
			
		||||
        blah += [{ rowid: rowid++, items: rowtpl }].map(_tpl.row).join``;
 | 
			
		||||
        rowtpl = "";
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    _container.thumbs.innerHTML = blah;
 | 
			
		||||
    //console.log( getpos( thumbs.querySelectorAll("div.row") ) );
 | 
			
		||||
    console.log( getposall( thumbs.querySelectorAll("div.row") ) );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function getpos(elems) {
 | 
			
		||||
    return [elems[0], elems[elems.length-1]].map(e => [e.children[0], e.parentNode].reduce((a, b) => a.offsetTop + b.offsetTop));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function getposall(elems) {
 | 
			
		||||
    return [...elems].map(e => [e.children[0], e.parentNode].reduce((a,b) => a.offsetTop + b.offsetTop));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function getItems(sum = 0, pos = "bottom") { // top/bottom
 | 
			
		||||
    sum = sum===0?_dims.eps:sum;
 | 
			
		||||
    Promise.all([
 | 
			
		||||
      fetch(`/api/test/?user=${rt.user}&mime=${rt.mime}&stamp=${rt.stamp}&eps=${sum}`),
 | 
			
		||||
      fetch(`/api/test/?user=${rt.user}&mime=${rt.mime}&stamp=${rt.stamp}&eps=${sum}&get=meta`)
 | 
			
		||||
    ])
 | 
			
		||||
    .then(res => Promise.all(res.map(muh => muh.json())))
 | 
			
		||||
    .then(data => {
 | 
			
		||||
      _cache = data[0].items[1].concat(data[0].items[0]).sort().reverse();
 | 
			
		||||
      /*return {
 | 
			
		||||
        act: data[0].items[0][0],
 | 
			
		||||
        items: data[0].items[1].concat(data[0].items[0]),
 | 
			
		||||
        items: [...data[0].items[1], ...data[0].items[0]],
 | 
			
		||||
        meta: data[1].meta
 | 
			
		||||
      };*/
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  getItems();
 | 
			
		||||
  setTimeout(() => { console.log(_cache); }, 1000);
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										73
									
								
								test3/style.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								test3/style.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,73 @@
 | 
			
		||||
* {
 | 
			
		||||
  padding: 0;
 | 
			
		||||
  margin: 0;
 | 
			
		||||
}
 | 
			
		||||
html, body {
 | 
			
		||||
  margin: 0;
 | 
			
		||||
  padding: 0;
 | 
			
		||||
  background-color: #262626;
 | 
			
		||||
  position: relative;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  color: #fff;
 | 
			
		||||
  font-family: Helvetica, Arial, sans-serif;
 | 
			
		||||
  font-size: 12px;
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
}
 | 
			
		||||
body {
 | 
			
		||||
  margin-top: 0 !important;
 | 
			
		||||
  padding-top: 0 !important;
 | 
			
		||||
}
 | 
			
		||||
a {
 | 
			
		||||
  color: #9f0;
 | 
			
		||||
  text-decoration: none;
 | 
			
		||||
}
 | 
			
		||||
a:hover {
 | 
			
		||||
  color: #74c100;
 | 
			
		||||
  text-decoration: underline;
 | 
			
		||||
}
 | 
			
		||||
div#page {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  margin: 0 auto;
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
  top: 22px;
 | 
			
		||||
  bottom: 16px;
 | 
			
		||||
}
 | 
			
		||||
div#thumbs {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  background-color: #040;
 | 
			
		||||
  top: 0;
 | 
			
		||||
  left: 0;
 | 
			
		||||
  bottom: 0;
 | 
			
		||||
  right: 0;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
}
 | 
			
		||||
a.thumb {
 | 
			
		||||
  width: 128px;
 | 
			
		||||
  height: 128px;
 | 
			
		||||
  margin: 0 8px 8px 0;
 | 
			
		||||
  float: left;
 | 
			
		||||
  outline: none;
 | 
			
		||||
  background-size: cover;
 | 
			
		||||
  background-position: center center;
 | 
			
		||||
  box-shadow: inset 0 0 10px #4c4a4a;
 | 
			
		||||
}
 | 
			
		||||
a.thumb:hover {
 | 
			
		||||
  opacity: 0.5;
 | 
			
		||||
  box-shadow: inset 0 0 10px #9f0;
 | 
			
		||||
}
 | 
			
		||||
.navbar {
 | 
			
		||||
  margin: 0 auto;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  border: 0;
 | 
			
		||||
  padding-top: 0;
 | 
			
		||||
  padding-bottom: 0;
 | 
			
		||||
  font-weight: bold;
 | 
			
		||||
  position: fixed;
 | 
			
		||||
  overflow: visible;
 | 
			
		||||
  z-index: 999;
 | 
			
		||||
  background-color: #484747;
 | 
			
		||||
  border-bottom: 2px solid #9f0;
 | 
			
		||||
  text-align: center;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										7
									
								
								test4/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								test4/README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
Frontend in Aktion (oder auch nicht) :⁾
 | 
			
		||||
 | 
			
		||||
https://dev.f0ck.space/misc/4
 | 
			
		||||
 | 
			
		||||
Benötigt wird:
 | 
			
		||||
Chromium (ab Version 61)
 | 
			
		||||
oder Firefox mit "dom.moduleScripts.enabled" auf true (about:config)
 | 
			
		||||
							
								
								
									
										98
									
								
								test4/css/style.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								test4/css/style.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,98 @@
 | 
			
		||||
* {
 | 
			
		||||
  padding: 0;
 | 
			
		||||
  margin: 0;
 | 
			
		||||
}
 | 
			
		||||
html, body {
 | 
			
		||||
  margin: 0;
 | 
			
		||||
  padding: 0;
 | 
			
		||||
  background-color: #262626;
 | 
			
		||||
  position: relative;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  color: #fff;
 | 
			
		||||
  font-family: Helvetica, Arial, sans-serif;
 | 
			
		||||
  font-size: 12px;
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
}
 | 
			
		||||
body {
 | 
			
		||||
  margin-top: 0 !important;
 | 
			
		||||
  padding-top: 0 !important;
 | 
			
		||||
}
 | 
			
		||||
a {
 | 
			
		||||
  color: #9f0;
 | 
			
		||||
  text-decoration: none;
 | 
			
		||||
}
 | 
			
		||||
a:hover {
 | 
			
		||||
  color: #74c100;
 | 
			
		||||
  text-decoration: underline;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
a.thumb {
 | 
			
		||||
  width: 128px;
 | 
			
		||||
  height: 128px;
 | 
			
		||||
  margin: 0 8px 8px 0;
 | 
			
		||||
  float: left;
 | 
			
		||||
  outline: none;
 | 
			
		||||
  background-size: cover;
 | 
			
		||||
  background-position: center center;
 | 
			
		||||
  box-shadow: inset 0 0 10px #4c4a4a;
 | 
			
		||||
}
 | 
			
		||||
a.thumb:hover {
 | 
			
		||||
  opacity: 0.5;
 | 
			
		||||
  box-shadow: inset 0 0 10px #9f0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div#page {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  margin: 0 auto;
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
  top: 22px;
 | 
			
		||||
  bottom: 16px;
 | 
			
		||||
}
 | 
			
		||||
div#thumbs {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  top: 0;
 | 
			
		||||
  left: 0;
 | 
			
		||||
  bottom: 0;
 | 
			
		||||
  right: 0;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  background-color: #040;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.navbar {
 | 
			
		||||
  margin: 0 auto;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  border: 0;
 | 
			
		||||
  padding-top: 0;
 | 
			
		||||
  padding-bottom: 0;
 | 
			
		||||
  font-weight: bold;
 | 
			
		||||
  position: fixed;
 | 
			
		||||
  overflow: visible;
 | 
			
		||||
  z-index: 999;
 | 
			
		||||
  background-color: #484747;
 | 
			
		||||
  border-bottom: 2px solid #9f0;
 | 
			
		||||
  text-align: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.pscroll {
 | 
			
		||||
  opacity: 0.7;
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  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: 3.2em;
 | 
			
		||||
}
 | 
			
		||||
div#down {
 | 
			
		||||
  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAANlBMVEUiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIjIyMiIiLm5uY3NzcqKipAQED///9KSkpHtWFIAAAACnRSTlMqACGx8/Cu6uerGsmyTAAAAM9JREFUeF7t1zkOwzAMBVEt3kLK2/0vm3KQivhWigTQ7+dBpZhyeW3+cNtSckqzd2xOafGu1TT1AVPyzv0YMIABDMD0fQB7u9S1HcCNXhAM4CAQZl98gZ8PgNsB3G69NwAEqQdAUHoABKUHQNB6AAStB0DQegAErQdA0HoABK0HQNB6AAShBwgE+gBACHuAWKCPAIS4B4gEegFAoHcFQKBXAAR6BUCgVwAEehlAoNcBt7Nd7TTXAYjD/uKDMYAB9B+etQ+o/cd3Lsv6NF9ryW9/v8EFMSsbFgAAAABJRU5ErkJggg==');
 | 
			
		||||
  bottom: 56px;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								test4/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								test4/index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
<!doctype blah>
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <title>f0ckv2 dev</title>
 | 
			
		||||
    <link href="./css/style.css" rel="stylesheet" />
 | 
			
		||||
    <meta charset="utf-8" />
 | 
			
		||||
    <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1" />
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div class="navbar"> </div>
 | 
			
		||||
    <div id="page">
 | 
			
		||||
      <div id="thumbs" style="top: 0;"></div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <script type="module" src="./js/main.js"></script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										43
									
								
								test4/js/api.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								test4/js/api.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
import rt from './runtimes.js';
 | 
			
		||||
import { render } from './helper.js';
 | 
			
		||||
 | 
			
		||||
export const api = {
 | 
			
		||||
  items: new Map(),
 | 
			
		||||
  meta: [],
 | 
			
		||||
  getItems: function() {
 | 
			
		||||
    return fetch("//api.allorigins.win/raw?url=https://f0ck.me/api/p", {
 | 
			
		||||
      headers: {
 | 
			
		||||
        //'Accept': 'application/json',
 | 
			
		||||
        //'Content-Type': 'application/json'
 | 
			
		||||
      },
 | 
			
		||||
      method: 'GET'
 | 
			
		||||
      //method: 'POST',
 | 
			
		||||
      //body: JSON.stringify({ ...rt.events.hash, eps: rt.events.dims.eps })
 | 
			
		||||
    })
 | 
			
		||||
    .then(res => res.status === 200? res.json() : {error:true} )
 | 
			
		||||
    .then(data => {
 | 
			
		||||
      if(!data.error) {
 | 
			
		||||
        this.meta = data.meta;
 | 
			
		||||
        [...data.items.prev, ...data.items.next].forEach(e => this.items.set(e.stamp, e));
 | 
			
		||||
      }
 | 
			
		||||
      return {
 | 
			
		||||
        prev: data.items.prev.sort().reverse(),
 | 
			
		||||
        next: data.items.next.sort().reverse()
 | 
			
		||||
      };
 | 
			
		||||
    })
 | 
			
		||||
    .then(data => {
 | 
			
		||||
      this.items = new Map([...this.items.entries()].sort().reverse());
 | 
			
		||||
      console.log(data);
 | 
			
		||||
    });
 | 
			
		||||
  },
 | 
			
		||||
  get pos() {
 | 
			
		||||
    return {
 | 
			
		||||
      latest: [...this.items][0],
 | 
			
		||||
      first: [...this.items][this.items.size - 1]
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
api.getItems().then(() => {
 | 
			
		||||
  render(api.items);
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										31
									
								
								test4/js/cfg.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								test4/js/cfg.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
export default {
 | 
			
		||||
  layout: {
 | 
			
		||||
    items: {
 | 
			
		||||
      size: 128, // imgsize
 | 
			
		||||
      gutter: 8 // padding
 | 
			
		||||
    },
 | 
			
		||||
    min_margin: 16,
 | 
			
		||||
    min_rows: 2,
 | 
			
		||||
    min_cols: 3
 | 
			
		||||
  },
 | 
			
		||||
  misc: {
 | 
			
		||||
    scrollrows: 4
 | 
			
		||||
  },
 | 
			
		||||
  api: {
 | 
			
		||||
    uri: "//f0ck.me/api/",
 | 
			
		||||
    modes: [
 | 
			
		||||
      "user",
 | 
			
		||||
      "mime",
 | 
			
		||||
      "new"
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
  tpl: {
 | 
			
		||||
    row: ({ rowid, items }) => `<div class="row" data-row="${rowid}">${items}</div>`,
 | 
			
		||||
    item: ({ id, }) => `<a href="//f0ck.me/${id}" class="thumb" style="background-image:url('//f0ck.me/t/${id}.png')"></a>`
 | 
			
		||||
  },
 | 
			
		||||
  container: {
 | 
			
		||||
    debug: document.querySelector("div.navbar"),
 | 
			
		||||
    page: document.querySelector("div#page"),
 | 
			
		||||
    thumbs: document.querySelector("div#thumbs")
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										83
									
								
								test4/js/events.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								test4/js/events.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,83 @@
 | 
			
		||||
import cfg from './cfg.js';
 | 
			
		||||
import { getposall } from './helper.js';
 | 
			
		||||
 | 
			
		||||
export const eventrt = {
 | 
			
		||||
  track: null,
 | 
			
		||||
  scroll: false,
 | 
			
		||||
  dims: null,
 | 
			
		||||
  hash: window.location.hash,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// <track>
 | 
			
		||||
const tracktopevent = new CustomEvent('top', { bubbles: true });
 | 
			
		||||
Object.defineProperty(cfg.container.thumbs, 'top', {
 | 
			
		||||
  set: function(top) {
 | 
			
		||||
    this.style.top = top;
 | 
			
		||||
    this.dispatchEvent(tracktopevent);
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export const tracktop = e => {
 | 
			
		||||
  eventrt.track = getposall(e.target.querySelectorAll("a.thumb"));
 | 
			
		||||
  //console.log(eventrt.track);
 | 
			
		||||
};
 | 
			
		||||
// </track>
 | 
			
		||||
 | 
			
		||||
// <scroll>
 | 
			
		||||
export const scroll = e => {
 | 
			
		||||
  if(e.preventDefault)
 | 
			
		||||
    e.preventDefault();
 | 
			
		||||
  const deltaY = e.deltaY < 0?-1:1; // - up, + down
 | 
			
		||||
 | 
			
		||||
  if(!eventrt.scroll) {
 | 
			
		||||
    eventrt.scroll = true;
 | 
			
		||||
    const dura = 500;
 | 
			
		||||
    const top = parseInt(cfg.container.thumbs.style.top.replace("px",""));
 | 
			
		||||
    const go = `${(top + (-deltaY * ((cfg.layout.items.size + cfg.layout.items.gutter) * cfg.misc.scrollrows)))}`;
 | 
			
		||||
    cfg.container.thumbs.animate( [{ top: `${top}px` }, { top: `${go}px` } ], { duration: dura } );
 | 
			
		||||
    setTimeout(() => { // after scroll
 | 
			
		||||
      cfg.container.thumbs.top = `${go}px`;
 | 
			
		||||
      eventrt.scroll = false;
 | 
			
		||||
 | 
			
		||||
      console.log( [...new Set([...cfg.container.thumbs.querySelectorAll("a.thumb")].map(e => {
 | 
			
		||||
        return [e.children[0], e.parentNode].reduce((a,b) => a.offsetTop + b.offsetTop);
 | 
			
		||||
      }))] );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    }, dura);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
// </scroll>
 | 
			
		||||
 | 
			
		||||
// <resize>
 | 
			
		||||
export const resize = e => {
 | 
			
		||||
  let rows = Math.max(~~((window.innerHeight - cfg.layout.min_margin + cfg.layout.items.size) / (cfg.layout.items.size + cfg.layout.items.gutter)), cfg.layout.min_rows);
 | 
			
		||||
  let cols = Math.max(~~((window.innerWidth - cfg.layout.min_margin) / (cfg.layout.items.size + cfg.layout.items.gutter)), cfg.layout.min_cols);
 | 
			
		||||
  let pageWidth = cols * (cfg.layout.items.size + cfg.layout.items.gutter);
 | 
			
		||||
  let margin = Math.max((window.innerWidth - pageWidth + cfg.layout.items.gutter) / cfg.layout.min_rows, 0);
 | 
			
		||||
  cfg.container.page.style.width = pageWidth;
 | 
			
		||||
  cfg.container.page.style.marginLeft = margin;
 | 
			
		||||
  eventrt.dims = {
 | 
			
		||||
    rows: rows,
 | 
			
		||||
    cols: cols,
 | 
			
		||||
    eps: rows * cols,
 | 
			
		||||
    pageWidth: pageWidth,
 | 
			
		||||
    margin: margin
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
// <resize>
 | 
			
		||||
 | 
			
		||||
// <hash>
 | 
			
		||||
export const hash = e => {
 | 
			
		||||
  eventrt.hash = window.location.hash;
 | 
			
		||||
  console.log(eventrt.hash);
 | 
			
		||||
};
 | 
			
		||||
// </hash>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// bind events
 | 
			
		||||
window.addEventListener("resize", resize);
 | 
			
		||||
window.dispatchEvent(new Event('resize'));
 | 
			
		||||
document.addEventListener("wheel", scroll);
 | 
			
		||||
cfg.container.thumbs.addEventListener('top', tracktop);
 | 
			
		||||
window.addEventListener("hashchange", hash);
 | 
			
		||||
							
								
								
									
										55
									
								
								test4/js/helper.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								test4/js/helper.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
			
		||||
import cfg from './cfg.js';
 | 
			
		||||
import rt from './runtimes.js';
 | 
			
		||||
 | 
			
		||||
export const getpos = elems => [elems[0], elems[elems.length-1]].map(e => [e.children[0], e.parentNode].reduce((a, b) => a.offsetTop + b.offsetTop));
 | 
			
		||||
export const getposall = elems => [...new Set([...elems].map(e => [e.children[0], e.parentNode].reduce((a,b) => a.offsetTop + b.offsetTop)))];
 | 
			
		||||
 | 
			
		||||
export const getlink = tmp => {
 | 
			
		||||
  const blah = {
 | 
			
		||||
    mode: "",
 | 
			
		||||
    user: "",
 | 
			
		||||
    mime: "",
 | 
			
		||||
    last: 0,
 | 
			
		||||
    post: 0
 | 
			
		||||
  };
 | 
			
		||||
  const api = "./api/";
 | 
			
		||||
  if(!tmp.match(/\,/))
 | 
			
		||||
    tmp = "#new";
 | 
			
		||||
  tmp = (tmp.match(/,/)?tmp:`${tmp},`).substr(1).split(",");
 | 
			
		||||
  const args = {
 | 
			
		||||
    l: tmp[0].split("/"),
 | 
			
		||||
    r: tmp[1].split("/")
 | 
			
		||||
  };
 | 
			
		||||
  blah.mode = ( args.l[0].length === 0 )? "new" : args.l[0];
 | 
			
		||||
  blah.last = parseInt(args.r[0]) || 0;
 | 
			
		||||
  blah.post = parseInt(args.r[1]) || 0;
 | 
			
		||||
  switch(blah.mode) {
 | 
			
		||||
    case "user":
 | 
			
		||||
      blah.user = ( args.l[1] )? args.l[1] : "";
 | 
			
		||||
      blah.mime = ( args.l[2] )? args.l[2] : "";
 | 
			
		||||
    break;
 | 
			
		||||
    case "mime":
 | 
			
		||||
      blah.user = ( args.l[2] )? args.l[2] : "";
 | 
			
		||||
      blah.mime = ( args.l[1] )? args.l[1] : "";
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
  return {
 | 
			
		||||
    mode: blah.mode,
 | 
			
		||||
    user: blah.user,
 | 
			
		||||
    stamp: blah.last,
 | 
			
		||||
    mime: blah.mime,
 | 
			
		||||
    eps: this._dims.eps,
 | 
			
		||||
    sort: this._lastmode
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const render = items => {
 | 
			
		||||
  items.forEach(item => {
 | 
			
		||||
    let thumb = document.createElement('a');
 | 
			
		||||
    thumb.className = "thumb";
 | 
			
		||||
    thumb.href = "#";
 | 
			
		||||
    thumb.style.backgroundImage = `url("//f0ck.me/t/${item.id}.png")`;
 | 
			
		||||
    thumb.append(document.createElement('dummy'));
 | 
			
		||||
    cfg.container.thumbs.append(thumb);
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										5
									
								
								test4/js/main.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								test4/js/main.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
import './helper.js';
 | 
			
		||||
import './events.js';
 | 
			
		||||
import './api.js';
 | 
			
		||||
 | 
			
		||||
import './swipe.js';
 | 
			
		||||
							
								
								
									
										5
									
								
								test4/js/runtimes.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								test4/js/runtimes.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
import { eventrt } from './events.js';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  events: eventrt,
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										67
									
								
								test4/js/swipe.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								test4/js/swipe.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
			
		||||
import { scroll } from './events.js';
 | 
			
		||||
import rt from './runtimes.js';
 | 
			
		||||
 | 
			
		||||
const eventtmp = {
 | 
			
		||||
  touchTracker: []
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const copyTouch = touch => {
 | 
			
		||||
  return {
 | 
			
		||||
    identifier: touch.identifier,
 | 
			
		||||
    screenX: touch.screenX,
 | 
			
		||||
    screenY: touch.screenY
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const getTrackedTouchIndex = identifier => {
 | 
			
		||||
  for(let i = 0; i < eventtmp.touchTracker.length; i++) {
 | 
			
		||||
    if(eventtmp.touchTracker[i].identifier == identifier)
 | 
			
		||||
      return i;
 | 
			
		||||
  }
 | 
			
		||||
  return -1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const removeTouch = identifier => {
 | 
			
		||||
  let index = getTrackedTouchIndex(ct.item(i).identifier);
 | 
			
		||||
  if(index === -1)
 | 
			
		||||
    return index;
 | 
			
		||||
  eventtmp.touchTracker.splice(index, 1);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const touchstart = e => {
 | 
			
		||||
  if(!rt.events.scroll) {
 | 
			
		||||
    const ct = e.changedTouches;
 | 
			
		||||
    for(let i = 0; i < e.changedTouches.length; i++)
 | 
			
		||||
      eventtmp.touchTracker.push(copyTouch(ct.item(i)));
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const touchmove = e => {
 | 
			
		||||
  e.preventDefault();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const touchend = e => {
 | 
			
		||||
  e.preventDefault();
 | 
			
		||||
  if(!rt.events.scroll) {
 | 
			
		||||
    let ct = e.changedTouches;
 | 
			
		||||
    for(let i = 0; i < ct.length; i++) {
 | 
			
		||||
      let index = getTrackedTouchIndex(ct.item(i).identifier);
 | 
			
		||||
      if(index !== -1) {
 | 
			
		||||
        let t = copyTouch(eventtmp.touchTracker[index]);
 | 
			
		||||
        if(Math.abs(Math.atan((ct.item(i).screenX - t.screenX) / (ct.item(i).screenY - t.screenY))) < 30)
 | 
			
		||||
          scroll({ deltaY: t.screenY > ct.item(i).screenY?1:-1 });
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const touchcancel = e => {
 | 
			
		||||
  e.preventDefault();
 | 
			
		||||
  const ct = e.changedTouches;
 | 
			
		||||
  ct.forEach(e => removeTouch(ct.item(ct).identifier));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
window.addEventListener("touchstart", touchstart);
 | 
			
		||||
window.addEventListener("touchmove", touchmove);
 | 
			
		||||
window.addEventListener("touchend", touchend);
 | 
			
		||||
window.addEventListener("touchcancel", touchcancel);
 | 
			
		||||
							
								
								
									
										15
									
								
								test5/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								test5/index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
<!doctype blah>
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <meta charset="utf-8">
 | 
			
		||||
    <title>f0ck-fe test</title>
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
			
		||||
    <link href="./style.css" rel="stylesheet" media="all">
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div id="page">
 | 
			
		||||
      <section id="wall"></section>
 | 
			
		||||
    </div>
 | 
			
		||||
    <script src="./script.js"></script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										95
									
								
								test5/script.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								test5/script.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,95 @@
 | 
			
		||||
let _layout = {
 | 
			
		||||
  items: {
 | 
			
		||||
    size: 128,
 | 
			
		||||
    gutter: 8
 | 
			
		||||
  },
 | 
			
		||||
  min_margin: 16,
 | 
			
		||||
  min_rows: 2,
 | 
			
		||||
  min_cols: 3
 | 
			
		||||
};
 | 
			
		||||
_tpl = {
 | 
			
		||||
  item: ({ id }) => `<article id="id${id}"><a href="#id${id}"><img src="//f0ck.me/t/${id}.png" /></a><div class="info"><div class="description"><h1>${id}</h1><p>Penis</p></div><ol><li>Infos lol</li><li>und so</li></ol></div></article>`
 | 
			
		||||
};
 | 
			
		||||
let rt = {
 | 
			
		||||
  user: "Flummi",
 | 
			
		||||
  mime: "",
 | 
			
		||||
  stamp: 1506717559,
 | 
			
		||||
  act: 0,
 | 
			
		||||
  items: new Map(),
 | 
			
		||||
  last: 0,
 | 
			
		||||
  first: 0,
 | 
			
		||||
};
 | 
			
		||||
let _cache = [];
 | 
			
		||||
let _dims = null;
 | 
			
		||||
let _scroll = false;
 | 
			
		||||
let _scrollrows = 4;
 | 
			
		||||
let _container = {
 | 
			
		||||
  page: document.querySelector("div#page"),
 | 
			
		||||
  wall: document.querySelector("section#wall")
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
window.onload = () => {
 | 
			
		||||
  function init() {
 | 
			
		||||
    let rows = Math.max(~~((window.innerHeight - _layout.min_margin + _layout.items.size) / (_layout.items.size + _layout.items.gutter)), _layout.min_rows);
 | 
			
		||||
    let cols = Math.max(~~((window.innerWidth - _layout.min_margin) / (_layout.items.size + _layout.items.gutter)), _layout.min_cols);
 | 
			
		||||
    let pageWidth = cols * (_layout.items.size + _layout.items.gutter);
 | 
			
		||||
    let margin = Math.max((window.innerWidth - pageWidth + _layout.items.gutter) / _layout.min_rows, 0);
 | 
			
		||||
    let page = _container.page;
 | 
			
		||||
    page.style.width = pageWidth;
 | 
			
		||||
    page.style.marginLeft = margin;
 | 
			
		||||
    _dims = {
 | 
			
		||||
      rows: rows,
 | 
			
		||||
      cols: cols,
 | 
			
		||||
      eps: rows * cols,
 | 
			
		||||
      pageWidth: pageWidth,
 | 
			
		||||
      margin: margin
 | 
			
		||||
    };
 | 
			
		||||
    //render();
 | 
			
		||||
  }
 | 
			
		||||
  function scroll(e) {
 | 
			
		||||
    if(e.preventDefault)
 | 
			
		||||
      e.preventDefault();
 | 
			
		||||
    let deltaY = e.deltaY < 0?-1:1; // - up, + down
 | 
			
		||||
 | 
			
		||||
    if(!_scroll) {
 | 
			
		||||
      _scroll = true;
 | 
			
		||||
      let dura = 500;
 | 
			
		||||
      let top = parseInt(_container.wall.style.top.replace("px",""));
 | 
			
		||||
      let go = `${(top + (-deltaY * ((_layout.items.size + _layout.items.gutter) * _scrollrows)))}`;
 | 
			
		||||
      _container.wall.animate( [{ top: `${top}px` }, { top: `${go}px` } ], { duration: dura } );
 | 
			
		||||
      setTimeout(() => { // after scroll
 | 
			
		||||
        _container.wall.style.top = `${go}px`;
 | 
			
		||||
        _scroll = false;
 | 
			
		||||
      }, dura);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  //document.addEventListener("wheel", scroll);
 | 
			
		||||
 | 
			
		||||
  function render() {
 | 
			
		||||
    let blah = "";
 | 
			
		||||
    _cache.forEach(e => {
 | 
			
		||||
      blah += [{ id: e.id }].map(_tpl.item).join``;
 | 
			
		||||
    });
 | 
			
		||||
    _container.wall.innerHTML = blah;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function getpos(elems) {
 | 
			
		||||
    return [elems[0], elems[elems.length-1]].map(e => [e.children[0], e.parentNode].reduce((a, b) => a.offsetTop + b.offsetTop));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function getposall(elems) {
 | 
			
		||||
    return [...elems].map(e => [e.children[0], e.parentNode].reduce((a,b) => a.offsetTop + b.offsetTop));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //api.allorigins.win/raw?url=https:
 | 
			
		||||
  function getItems(sum = 0, pos = "bottom") { // top/bottom
 | 
			
		||||
    fetch(`//f0ck.me/api/user/${rt.user}`)
 | 
			
		||||
      .then(res => res.json())
 | 
			
		||||
      .then(data => _cache = data);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  init();
 | 
			
		||||
  getItems();
 | 
			
		||||
  setTimeout(() => { render(); }, 500);
 | 
			
		||||
  setTimeout(() => { console.log(_cache); }, 1000);
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										341
									
								
								test5/style.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										341
									
								
								test5/style.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,341 @@
 | 
			
		||||
html, body, div, span, applet, object, iframe,
 | 
			
		||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
 | 
			
		||||
a, abbr, acronym, address, big, cite, code,
 | 
			
		||||
del, dfn, em, img, ins, kbd, q, s, samp,
 | 
			
		||||
small, strike, strong, sub, sup, tt, var,
 | 
			
		||||
b, u, i, center,
 | 
			
		||||
dl, dt, dd, ol, ul, li,
 | 
			
		||||
fieldset, form, label, legend,
 | 
			
		||||
table, caption, tbody, tfoot, thead, tr, th, td,
 | 
			
		||||
article, aside, canvas, details, embed,
 | 
			
		||||
figure, figcaption, footer, header, hgroup,
 | 
			
		||||
menu, nav, output, ruby, section, summary,
 | 
			
		||||
time, mark, audio, video {
 | 
			
		||||
  margin: 0;
 | 
			
		||||
  padding: 0;
 | 
			
		||||
  border: 0;
 | 
			
		||||
  font-size: 100%;
 | 
			
		||||
  font: inherit;
 | 
			
		||||
  vertical-align: baseline;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
article, aside, details, figcaption, figure,
 | 
			
		||||
footer, header, hgroup, menu, nav, section {
 | 
			
		||||
  display: block;
 | 
			
		||||
}
 | 
			
		||||
body {
 | 
			
		||||
  line-height: 1;
 | 
			
		||||
}
 | 
			
		||||
ol, ul {
 | 
			
		||||
  list-style: none;
 | 
			
		||||
}
 | 
			
		||||
blockquote, q {
 | 
			
		||||
  quotes: none;
 | 
			
		||||
}
 | 
			
		||||
blockquote:before, blockquote:after,
 | 
			
		||||
q:before, q:after {
 | 
			
		||||
  content: '';
 | 
			
		||||
  content: none;
 | 
			
		||||
}
 | 
			
		||||
table {
 | 
			
		||||
  border-collapse: collapse;
 | 
			
		||||
  border-spacing: 0;
 | 
			
		||||
}
 | 
			
		||||
body {
 | 
			
		||||
  background: #333;
 | 
			
		||||
  color: white;
 | 
			
		||||
  font-family: "Noto Sans", Tahoma, sans-serif;
 | 
			
		||||
}
 | 
			
		||||
h1 {
 | 
			
		||||
  font-size: 2em;
 | 
			
		||||
}
 | 
			
		||||
section {
 | 
			
		||||
  max-width: 1600px;
 | 
			
		||||
  margin: 0 auto;
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
  position: relative;
 | 
			
		||||
}
 | 
			
		||||
section article {
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  *display: inline;
 | 
			
		||||
  zoom: 1;
 | 
			
		||||
  padding: 5px;
 | 
			
		||||
  vertical-align: top;
 | 
			
		||||
  width: 50%;
 | 
			
		||||
}
 | 
			
		||||
section article:nth-child(2n+1) .info {
 | 
			
		||||
  left: 0;
 | 
			
		||||
}
 | 
			
		||||
section article:nth-child(2n+2) .info {
 | 
			
		||||
  left: -100%;
 | 
			
		||||
}
 | 
			
		||||
section img {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: auto;
 | 
			
		||||
}
 | 
			
		||||
section .info {
 | 
			
		||||
  width: 180%;
 | 
			
		||||
  padding: 2em 0;
 | 
			
		||||
  margin: 0 10%;
 | 
			
		||||
  position: relative;
 | 
			
		||||
  float: left;
 | 
			
		||||
  opacity: 0;
 | 
			
		||||
  height: 0;
 | 
			
		||||
  font-size: 0;
 | 
			
		||||
}
 | 
			
		||||
section .info h1 {
 | 
			
		||||
  margin-bottom: .5em;
 | 
			
		||||
}
 | 
			
		||||
section .info p,
 | 
			
		||||
section .info ol {
 | 
			
		||||
  margin-bottom: 2em;
 | 
			
		||||
  line-height: 140%;
 | 
			
		||||
}
 | 
			
		||||
section .info ol {
 | 
			
		||||
    margin-left: 20px;
 | 
			
		||||
}
 | 
			
		||||
section .info li {
 | 
			
		||||
  list-style: decimal;
 | 
			
		||||
  line-height: 140%;
 | 
			
		||||
}
 | 
			
		||||
section .info .purchase {
 | 
			
		||||
  display: block;
 | 
			
		||||
  margin-top: .4em;
 | 
			
		||||
  padding: .4em;
 | 
			
		||||
  background: #006699;
 | 
			
		||||
  color: white;
 | 
			
		||||
  text-decoration: none;
 | 
			
		||||
  text-transform: uppercase;
 | 
			
		||||
  text-align: center;
 | 
			
		||||
  font-size: 1.4em;
 | 
			
		||||
  -webkit-transition: 0.5s background-color;
 | 
			
		||||
  -moz-transition: 0.5s background-color;
 | 
			
		||||
  -ms-transition: 0.5s background-color;
 | 
			
		||||
  -o-transition: 0.5s background-color;
 | 
			
		||||
  transition: 0.5s background-color;
 | 
			
		||||
}
 | 
			
		||||
section .info .purchase:hover {
 | 
			
		||||
  background: #0066CC;
 | 
			
		||||
}
 | 
			
		||||
section article:target .info {
 | 
			
		||||
  height: auto;
 | 
			
		||||
  font-size: 100%;
 | 
			
		||||
  opacity: 1;
 | 
			
		||||
  -webkit-transition: .5s .5s opacity;
 | 
			
		||||
  -moz-transition: .5s .5s opacity;
 | 
			
		||||
  -ms-transition: .5s .5s opacity;
 | 
			
		||||
  -o-transition: .5s .5s opacity;
 | 
			
		||||
  transition: .5s .5s opacity;
 | 
			
		||||
}
 | 
			
		||||
section article:target img {
 | 
			
		||||
  -webkit-box-shadow: 0 8px 3px -5px rgba(0,0,0,.5);
 | 
			
		||||
  -moz-box-shadow: 0 8px 3px -5px rgba(0,0,0,.5);
 | 
			
		||||
  box-shadow: 0 8px 3px -5px rgba(0,0,0,.5);
 | 
			
		||||
  -webkit-transform: scale(1.1);
 | 
			
		||||
  -moz-transform: scale(1.1);
 | 
			
		||||
  -ms-transform: scale(1.1);
 | 
			
		||||
  -o-transform: scale(1.1);
 | 
			
		||||
  transform: scale(1.1);
 | 
			
		||||
  -webkit-transition: .5s;
 | 
			
		||||
  -moz-transition: .5s;
 | 
			
		||||
  -ms-transition: .5s;
 | 
			
		||||
  -o-transition: .5s;
 | 
			
		||||
  transition: .5s;
 | 
			
		||||
}
 | 
			
		||||
footer {
 | 
			
		||||
  min-height: 400px;
 | 
			
		||||
  padding: 4em 1em;
 | 
			
		||||
  background: black;
 | 
			
		||||
  font-size: 1em;
 | 
			
		||||
  word-break: break-word;
 | 
			
		||||
}
 | 
			
		||||
footer .credits {
 | 
			
		||||
  width: 250px;
 | 
			
		||||
}
 | 
			
		||||
footer .credits li {
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  width: 32%;
 | 
			
		||||
}
 | 
			
		||||
footer a {
 | 
			
		||||
  color: white;
 | 
			
		||||
}
 | 
			
		||||
footer h2 {
 | 
			
		||||
  font-size: 1.6em;
 | 
			
		||||
}
 | 
			
		||||
footer h1,
 | 
			
		||||
footer h2,
 | 
			
		||||
footer p,
 | 
			
		||||
footer ul {
 | 
			
		||||
  line-height: 140%;
 | 
			
		||||
  margin-bottom: 1em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media only screen and (min-width: 400px) {
 | 
			
		||||
  section article {
 | 
			
		||||
    width: 33.333333%;
 | 
			
		||||
  }
 | 
			
		||||
  section article .info {
 | 
			
		||||
    width: 280%;
 | 
			
		||||
  }
 | 
			
		||||
  section article .purchase {
 | 
			
		||||
    display: inline-block;
 | 
			
		||||
    *display: inline;
 | 
			
		||||
    zoom: 1;
 | 
			
		||||
    float: left;
 | 
			
		||||
    clear: both;
 | 
			
		||||
    width: auto;
 | 
			
		||||
    margin-top: 2em 0 0 0;
 | 
			
		||||
  }
 | 
			
		||||
  section article .description {
 | 
			
		||||
    float: left;
 | 
			
		||||
    width: 50%;
 | 
			
		||||
  }
 | 
			
		||||
  section article ol {
 | 
			
		||||
    float: right;
 | 
			
		||||
    width: 30%;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(3n+1) .info {
 | 
			
		||||
    left: 0;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(3n+2) .info {
 | 
			
		||||
    left: -100%;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(3n+3) .info {
 | 
			
		||||
    left: -200%;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media only screen and (min-width: 600px) {
 | 
			
		||||
  section article .info {
 | 
			
		||||
    width: 380%;
 | 
			
		||||
  }
 | 
			
		||||
  section article {
 | 
			
		||||
    width: 25%;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(4n+1) .info {
 | 
			
		||||
    left: 0;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(4n+2) .info {
 | 
			
		||||
    left: -100%;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(4n+3) .info {
 | 
			
		||||
    left: -200%;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(4n+4) .info {
 | 
			
		||||
    left: -300%;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media only screen and (min-width: 800px) {
 | 
			
		||||
  section article .info {
 | 
			
		||||
    width: 480%;
 | 
			
		||||
  }
 | 
			
		||||
  section article {
 | 
			
		||||
    width: 20%;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(5n+1) .info {
 | 
			
		||||
    left: 0;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(5n+2) .info {
 | 
			
		||||
    left: -100%;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(5n+3) .info {
 | 
			
		||||
    left: -200%;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(5n+4) .info {
 | 
			
		||||
    left: -300%;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(5n+5) .info {
 | 
			
		||||
    left: -400%;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media only screen and (min-width: 1000px) {
 | 
			
		||||
  section article .info {
 | 
			
		||||
    width: 580%;
 | 
			
		||||
  }
 | 
			
		||||
  section article {
 | 
			
		||||
    width: 16.6666667%;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(6n+1) .info {
 | 
			
		||||
    left: 0;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(6n+2) .info {
 | 
			
		||||
    left: -100%;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(6n+3) .info {
 | 
			
		||||
    left: -200%;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(6n+4) .info {
 | 
			
		||||
    left: -300%;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(6n+5) .info {
 | 
			
		||||
    left: -400%;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(6n+6) .info {
 | 
			
		||||
    left: -500%;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media only screen and (min-width: 1200px) {
 | 
			
		||||
  section article .info {
 | 
			
		||||
    width: 680%;
 | 
			
		||||
  }
 | 
			
		||||
  section article {
 | 
			
		||||
    width: 14.2857143%;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(7n+1) .info {
 | 
			
		||||
    left: 0;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(7n+2) .info {
 | 
			
		||||
    left: -100%;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(7n+3) .info {
 | 
			
		||||
    left: -200%;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(7n+4) .info {
 | 
			
		||||
    left: -300%;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(7n+5) .info {
 | 
			
		||||
    left: -400%;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(7n+6) .info {
 | 
			
		||||
    left: -500%;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(7n+7) .info {
 | 
			
		||||
    left: -600%;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media only screen and (min-width: 1400px) {
 | 
			
		||||
  section article .info {
 | 
			
		||||
    width: 780%;
 | 
			
		||||
  }
 | 
			
		||||
  section article {
 | 
			
		||||
    width: 12.5%;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(8n+1) .info {
 | 
			
		||||
    left: 0;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(8n+2) .info {
 | 
			
		||||
    left: -100%;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(8n+3) .info {
 | 
			
		||||
    left: -200%;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(8n+4) .info {
 | 
			
		||||
    left: -300%;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(8n+5) .info {
 | 
			
		||||
    left: -400%;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(8n+6) .info {
 | 
			
		||||
    left: -500%;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(8n+7) .info {
 | 
			
		||||
    left: -600%;
 | 
			
		||||
  }
 | 
			
		||||
  section article:nth-child(8n+8) .info {
 | 
			
		||||
    left: -700%;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user