Created
November 2, 2022 22:10
-
-
Save Ryu1845/7a1cbf39d10cdf9feecda3e96c857e00 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>SNScrape Viewer</title> | |
<script src="https://unpkg.com/mustache@latest"></script> | |
<script src="https://cdn.tailwindcss.com"></script> | |
<script> | |
function checkVisible(elm, threshold, mode) { | |
threshold = threshold || 0; | |
mode = mode || 'visible'; | |
var rect = elm.getBoundingClientRect(); | |
var viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight); | |
var above = rect.bottom - threshold < 0; | |
var below = rect.top - viewHeight + threshold >= 0; | |
return mode === 'above' ? above : (mode === 'below' ? below : !above && !below); | |
} | |
function insertAfter(newNode, existingNode) { | |
existingNode.parentNode.insertBefore(newNode, existingNode.nextSibling); | |
} | |
async function loadTweets() { | |
const [file] = document.querySelector('input[type=file]').files; | |
var lines; | |
if (file) { | |
var text = await file.text(); | |
lines = text.split(/\r\n|\n/); | |
} | |
return new Promise((resolve) => {resolve(lines)}); | |
} | |
function makeTweetArray(lines, prevRange, currRange) { | |
var template = document.getElementById('template').innerHTML; | |
var oldDiv; | |
var newDiv; | |
var tweets = []; | |
for(var line = prevRange; line < lines.length-1 && line < currRange; line++){ | |
newDiv = document.createElement("div"); | |
newDiv.id = line; | |
var rendered = Mustache.render(template, JSON.parse(lines[line])); | |
newDiv.innerHTML = rendered; | |
tweets.push(newDiv); | |
} | |
return tweets; | |
} | |
async function mainFunc() { | |
var target = document.getElementById('target'); | |
var container = document.createElement("div"); | |
container.id = "container"; | |
document.body.insertBefore(container, target); | |
let lines = await loadTweets(); | |
const paginationNumbers = document.getElementById("pagination-numbers"); | |
const nextButton = document.getElementById("next-button"); | |
const prevButton = document.getElementById("prev-button"); | |
const pageNumber = document.getElementById("page-number"); | |
const paginationLimit = 5; | |
const pageCount = Math.ceil(lines.length / paginationLimit) - 1; | |
pageNumber.max = pageCount; | |
let currentPage = 1; | |
const disableButton = (button) => { | |
button.classList.add("disabled"); | |
button.setAttribute("disabled", true); | |
}; | |
const enableButton = (button) => { | |
button.classList.remove("disabled"); | |
button.removeAttribute("disabled"); | |
}; | |
const handlePageButtonsStatus = () => { | |
if (currentPage === 1) { | |
disableButton(prevButton); | |
} else { | |
enableButton(prevButton); | |
} | |
if (pageCount === currentPage) { | |
disableButton(nextButton); | |
} else { | |
enableButton(nextButton); | |
} | |
}; | |
const handleActivePageNumber = () => { | |
document.querySelectorAll(".pagination-number").forEach((button) => { | |
button.classList.remove("active"); | |
const pageIndex = Number(button.getAttribute("page-index")); | |
if (pageIndex == currentPage) { | |
button.classList.add("active"); | |
} | |
}); | |
}; | |
const getPageNumber = (index) => { | |
const pageNumber = document.createElement("button"); | |
pageNumber.className = "pagination-number"; | |
pageNumber.innerHTML = index; | |
pageNumber.setAttribute("page-index", index); | |
pageNumber.setAttribute("aria-label", "Page " + index); | |
return pageNumber; | |
}; | |
const getPaginationNumbers = () => { | |
console.log(pageNumber); | |
let one = getPageNumber(1); | |
paginationNumbers.insertBefore(one, pageNumber) | |
let last = getPageNumber(pageCount); | |
insertAfter(last, pageNumber); | |
}; | |
const setCurrentPage = (pageNum) => { | |
container.innerHTML = ''; | |
currentPage = pageNum; | |
handleActivePageNumber(); | |
handlePageButtonsStatus(); | |
const prevRange = (pageNum - 1) * paginationLimit; | |
const currRange = pageNum * paginationLimit; | |
let tweets = makeTweetArray(lines, prevRange, currRange); | |
target = document.getElementById('target'); | |
tweets.forEach((tweet) => {container.append(tweet)}); | |
}; | |
getPaginationNumbers(); | |
setCurrentPage(1); | |
pageNumber.oninput = () => { | |
console.log(document.getElementById("page-number").value); | |
setCurrentPage(document.getElementById("page-number").value); | |
} | |
prevButton.addEventListener("click", () => { | |
setCurrentPage(currentPage - 1); | |
}); | |
nextButton.addEventListener("click", () => { | |
setCurrentPage(currentPage + 1); | |
}); | |
document.querySelectorAll(".pagination-number").forEach((button) => { | |
const pageIndex = Number(button.getAttribute("page-index")); | |
if (pageIndex) { | |
button.addEventListener("click", () => { | |
setCurrentPage(pageIndex); | |
}); | |
} | |
}); | |
} | |
</script> | |
<style type="text/css" media="screen"> | |
.pagination-container { | |
width: calc(100% - 2rem); | |
display: flex; | |
align-items: center; | |
position: absolute; | |
bottom: 0; | |
padding: 1rem 0; | |
justify-content: center; | |
} | |
.pagination-number, | |
.pagination-button{ | |
font-size: 1.1rem; | |
background-color: transparent; | |
border: none; | |
margin: 0.25rem 0.25rem; | |
cursor: pointer; | |
height: 2.5rem; | |
width: 2.5rem; | |
border-radius: .2rem; | |
} | |
.pagination-number:hover, | |
.pagination-button:not(.disabled):hover { | |
background: #fff; | |
} | |
.pagination-number.active { | |
color: #fff; | |
background: #0085b6; | |
} | |
</style> | |
</head> | |
<body> | |
<script id="template" type="x-tmpl-mustache"> | |
<!-- component --> | |
<div class="font-sans rounded border px-6 py-4 max-w-md"> | |
<div class="flex items-center"> | |
<img src="{{user.profileImageUrl}}" class="h-12 w-12 rounded-full" /> | |
<div class="flex flex-col ml-4"> | |
<a class="font-bold text-black" href="#">{{user.username}}</a> | |
<span class="text-grey">@{{user.username}}</span> | |
</div> | |
<svg viewBox="328 355 335 276" class="ml-auto" height="24" width="24" xmlns="http://www.w3.org/2000/svg"> | |
<path d=" M 630, 425 A 195, 195 0 0 1 331, 600 A 142, 142 0 0 0 428, 570 A 70, 70 0 0 1 370, 523 A 70, 70 0 0 0 401, 521 A 70, 70 0 0 1 344, 455 A 70, 70 0 0 0 372, 460 A 70, 70 0 0 1 354, 370 A 195, 195 0 0 0 495, 442 A 67, 67 0 0 1 611, 380 A 117, 117 0 0 0 654, 363 A 65, 65 0 0 1 623, 401 A 117, 117 0 0 0 662, 390 A 65, 65 0 0 1 630, 425 Z" style="fill:#3BA9EE;"/> | |
</svg> | |
</div> | |
<div class=" mt-3 mb-1 leading-normal text-lg">{{renderedContent}}</div> | |
<div class="text-grey mb-3 text-sm"></div> | |
<div class="flex text-grey"> | |
<div class="flex items-center mr-4"> | |
<svg class="mr-2" width="24" height="24" viewBox="0 0 24 24"><path class="fill-current" d="M14.046 2.242l-4.148-.01h-.002c-4.374 0-7.8 3.427-7.8 7.802 0 4.098 3.186 7.206 7.465 7.37v3.828c0 .108.045.286.12.403.143.225.385.347.633.347.138 0 .277-.038.402-.118.264-.168 6.473-4.14 8.088-5.506 1.902-1.61 3.04-3.97 3.043-6.312v-.017c-.006-4.368-3.43-7.788-7.8-7.79zm3.787 12.972c-1.134.96-4.862 3.405-6.772 4.643V16.67c0-.414-.334-.75-.75-.75h-.395c-3.66 0-6.318-2.476-6.318-5.886 0-3.534 2.768-6.302 6.3-6.302l4.147.01h.002c3.532 0 6.3 2.766 6.302 6.296-.003 1.91-.942 3.844-2.514 5.176z"/></svg> | |
<span>{{replyCount}}</span> | |
</div> | |
<div class="flex items-center mr-4"> | |
<svg class="mr-2" width="24" height="24" viewBox="0 0 24 24"><path class="fill-current" d="M23.77 15.67c-.292-.293-.767-.293-1.06 0l-2.22 2.22V7.65c0-2.068-1.683-3.75-3.75-3.75h-5.85c-.414 0-.75.336-.75.75s.336.75.75.75h5.85c1.24 0 2.25 1.01 2.25 2.25v10.24l-2.22-2.22c-.293-.293-.768-.293-1.06 0s-.294.768 0 1.06l3.5 3.5c.145.147.337.22.53.22s.383-.072.53-.22l3.5-3.5c.294-.292.294-.767 0-1.06zm-10.66 3.28H7.26c-1.24 0-2.25-1.01-2.25-2.25V6.46l2.22 2.22c.148.147.34.22.532.22s.384-.073.53-.22c.293-.293.293-.768 0-1.06l-3.5-3.5c-.293-.294-.768-.294-1.06 0l-3.5 3.5c-.294.292-.294.767 0 1.06s.767.293 1.06 0l2.22-2.22V16.7c0 2.068 1.683 3.75 3.75 3.75h5.85c.414 0 .75-.336.75-.75s-.337-.75-.75-.75z"/></svg> | |
<span>{{retweetCount}}</span> | |
</div> | |
<div class="flex items-center"> | |
<svg class="mr-2" width="24" height="24" viewBox="0 0 24 24"><path class="fill-current" d="M12 21.638h-.014C9.403 21.59 1.95 14.856 1.95 8.478c0-3.064 2.525-5.754 5.403-5.754 2.29 0 3.83 1.58 4.646 2.73.813-1.148 2.353-2.73 4.644-2.73 2.88 0 5.404 2.69 5.404 5.755 0 6.375-7.454 13.11-10.037 13.156H12zM7.354 4.225c-2.08 0-3.903 1.988-3.903 4.255 0 5.74 7.035 11.596 8.55 11.658 1.52-.062 8.55-5.917 8.55-11.658 0-2.267-1.822-4.255-3.902-4.255-2.528 0-3.94 2.936-3.952 2.965-.23.562-1.156.562-1.387 0-.015-.03-1.426-2.965-3.955-2.965z"/></svg> | |
<span>{{likeCount}}</span> | |
</div> | |
</div> | |
</div> | |
</script> | |
<div> | |
<input type="file" onchange="mainFunc()" id="choose-file" name="choose-file" /> | |
</div> | |
<div id="target"></div> | |
<nav class="pagination-container"> | |
<button class="pagination-button" id="prev-button" aria-label="Previous page" title="Previous page"> | |
< | |
</button> | |
<div id="pagination-numbers"> | |
<input type="number" id="page-number" name="page-number" min=1> | |
</div> | |
<button class="pagination-button" id="next-button" aria-label="Next page" title="Next page"> | |
> | |
</button> | |
</nav> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment