reddit/app/templates/index.html

348 lines
11 KiB
HTML
Executable File

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Reddit, but better</title>
<style>
:root {
--dark: #2c2c2c;
--darker: #171717;
--light: #bfbfbf;
--confirm: #970000;
}
html {
height: 100%;
}
body {
background-color: var(--darker);
color: var(--light);
min-height: 100%;
margin: 0; /* Removes default browser margin */
}
img, video {
max-width: 100%;
width: auto;
height: auto;
}
div.post {
background-color: var(--dark);
border: 2px solid var(--light);
border-radius: 15px;
padding: 10px;
margin-bottom: 20px;
}
.sidebar {
outline: 2px solid var(--light);
position: sticky;
top: 0;
left: 0;
background-color: var(--dark);
display: flex;
flex-wrap: nowrap;
z-index: 1000;
}
.content {
display: flex;
flex-grow: 1; /* Takes up remaining space */
flex-direction: column;
}
/* desktop */
@media (min-aspect-ratio: 1) {
img, video {
max-height: 80vh;
}
div.post {
width: 70vw;
}
.container {
display: flex;
flex-direction: row;
}
.sidebar {
width: fit-content;
height: 100vh;
flex-direction: column;
overflow-y: auto;
padding: 5px;
margin-right: 20px;
}
}
/* phone */
@media (max-aspect-ratio: 1) {
img, video {
max-height: 100vh;
}
div.post {
width: calc(100vw - 50px);
margin-top: 10px;
}
.container {
display: flex;
flex-direction: column;
}
.sidebar {
width: 100vw;
height: 50px;
flex-direction: row;
overflow-x: auto;
align-items: center;
padding-top: 5px;
padding-bottom: 5px;
margin-bottom: 10px;
}
.content {
align-items: center;
}
}
.sidebar a {
display: block;
color: var(--light);
text-decoration: none;
white-space: nowrap;
margin: 5px;
padding: 5px;
}
.sidebar a:hover {
background-color: var(--darker);
color: var(--light);
}
.invert {
filter: invert(1);
transition: filter 0.3s;
}
.button-wrapper {
display: flex;
width: 100%;
gap: 10px;
margin-top: 10px;
}
.button-wrapper.gallery {
gap: 5px;
}
.button-wrapper button {
flex: 1;
padding: 10px;
cursor: pointer;
background-color: var(--darker);
color: var(--light);
border: 2px solid var(--light);
border-radius: 10px;
font-size: 1.25rem;
font-weight: bold;
}
.button-wrapper button.confirm {
background-color: var(--confirm)
}
.button-wrapper button.gallery {
padding: 5px;
background-color: var(--darker);
border-radius: 5px;
border: none;
cursor: none;
}
.button-wrapper button.gallery.selected {
background-color: var(--light);
}
.text-content {
overflow: hidden;
transition: max-height 0.3s ease-out; /* Smooth transition */
max-height: 20vh;
position: relative;
}
.text-content::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 30px;
background: linear-gradient(to bottom, rgba(255,255,255,0), var(--dark));
}
.text-content.expanded {
max-height: 1000vh;
}
.text-content.expanded::after {
display: none;
}
</style>
</head>
<body>
<div class="container">
<div class="sidebar">
{% for subreddit in subreddits %}
<a href="{{ subreddit }}">{{ subreddit }}</a>
{% endfor %}
</div>
<div class="content">
<h1>{{ title }}</h1>
{% for post in posts %}
<div class="post">
<h3>{{ post.title }}</h3>
{% if post.subreddit %}
<h5>{{ post.subreddit }}</h5>
{% endif %}
{% if post.media_html|length > 0 %}
<div class="media-div">
{% for media in post.media_html %}
{{ media|safe }}
{% endfor %}
{% if post.media_html|length > 1 %}
<span class="button-wrapper gallery">
</span>
{% endif %}
</div>
{% endif %}
{% if post.body %}
<div class="text-content" onclick="expand(this)">
{{ post.body }}
</div>
{% endif %}
<span class="button-wrapper">
<button type="button" onclick='comments("{{ post.permalink }}")'>Comments</button>
<button type="button" onclick='hide(this, "{{ post.permalink }}")'>Hide</button>
</span>
</div>
{% endfor %}
</div>
</div>
<script>
// setup galleries
mediaDivs = document.querySelectorAll('.media-div');
mediaDivs.forEach(div => {
images = Array.from(div.querySelectorAll('img'));
if (images.length > 1) {
buttonSpan = div.querySelector('.button-wrapper:first-of-type');
images.forEach(image => {
image.addEventListener('click', (e) => {
if (e.offsetX > image.offsetWidth * 2 / 3) {
// scroll right
div = e.target.closest('.media-div');
images = Array.from(div.querySelectorAll('img'));
currentIndex = images.indexOf(e.target)
if (currentIndex < (images.length -1)) {
buttons = Array.from(div.querySelectorAll('button'));
images[currentIndex].style.display = "none";
images[currentIndex+1].style.display = "block";
buttons[currentIndex].classList.remove('selected');
buttons[currentIndex+1].classList.add('selected');
} else {
e.target.classList.toggle('invert');
}
} else if (e.offsetX < image.offsetWidth / 3) {
// scroll left
div = e.target.closest('.media-div');
images = Array.from(div.querySelectorAll('img'));
currentIndex = images.indexOf(e.target)
if (currentIndex > 0) {
buttons = Array.from(div.querySelectorAll('button'));
images[currentIndex].style.display = "none";
images[currentIndex-1].style.display = "block";
buttons[currentIndex].classList.remove('selected');
buttons[currentIndex-1].classList.add('selected');
} else {
e.target.classList.toggle('invert');
}
} else {
image.classList.toggle('invert');
}
});
});
firstImage = images.shift();
firstButton = document.createElement('button');
firstButton.classList.add('gallery');
firstButton.classList.add('selected');
buttonSpan.appendChild(firstButton);
images.forEach(image => {
image.style.display = "none";
button = document.createElement('button');
button.classList.add('gallery');
buttonSpan.appendChild(button);
});
} else {
images.forEach(image => {
image.addEventListener('click', () => {
image.classList.toggle('invert');
});
});
}
});
// main button code
function hide(button, permalink){
if (button.classList.contains('confirm')) {
div = button.closest('.post');
div.remove();
try {
fetch('/hide' + permalink);
} catch (error) {
console.error('Could not hide', error);
}
} else {
button.classList.add('confirm');
}
}
function comments(permalink){
window.open("https://reddit.com" + permalink, '_blank');
}
// text expand code
function checkHeight(){
const divs = document.querySelectorAll('.text-content');
divs.forEach(div => {
height = div.offsetHeight;
style = window.getComputedStyle(div);
maxHeight = parseInt(style.maxHeight);
if (height < maxHeight) {
div.classList.add('expanded');
}
});
}
function expand(div) {
div.classList.add('expanded');
}
window.addEventListener('load', (event) => {
checkHeight()
});
window.addEventListener('resize', (event) => {
checkHeight()
});
// audio/video sync code
function findAudio(video){
const div = video.closest('.post');
return div.querySelector('audio:first-of-type');
}
function playAudio(video){
audio = findAudio(video);
if (audio) {
audio.play();
audio.currentTime = video.currentTime;
}
}
function pauseAudio(video){
audio = findAudio(video);
if (audio) {
audio.pause();
audio.currentTime = video.currentTime;
}
}
function seekAudio(video){
audio = findAudio(video);
if (audio) {
audio.currentTime = video.currentTime;
}
}
</script>
</body>
</html>