Don't limit post height, add left/right hand toggle to header which controls which side hide appears on

This commit is contained in:
John Stephani 2026-01-18 22:54:05 -06:00
parent d9944a88a1
commit 192d4e739e
4 changed files with 350 additions and 422 deletions

View File

@ -117,6 +117,7 @@ def front_page():
connection = sqlite3.connect(config.db_file)
cursor = connection.cursor()
sidebar_links = get_sidebar_links(cursor)
right_handed = get_config('side')!='left'
sort = get_config("sort") or "created_utc asc"
select = f"""
SELECT
@ -138,7 +139,8 @@ def front_page():
title=title,
posts=posts,
sidebar_links=sidebar_links,
sort=sort.split())
sort=sort.split(),
right_handed=right_handed)
@app.route('/r/other')
def other_page():
@ -146,6 +148,7 @@ def other_page():
connection = sqlite3.connect(config.db_file)
cursor = connection.cursor()
sidebar_links = get_sidebar_links(cursor)
right_handed = get_config('side')!='left'
sort = get_config("sort") or "created_utc asc"
select = f"""
SELECT
@ -187,7 +190,8 @@ def other_page():
title=title,
posts=posts,
sidebar_links=sidebar_links,
sort=sort.split())
sort=sort.split(),
right_handed=right_handed)
@app.route('/r/saved')
def get_saved():
@ -195,6 +199,7 @@ def get_saved():
connection = sqlite3.connect(config.db_file)
cursor = connection.cursor()
sidebar_links = get_sidebar_links(cursor)
right_handed = get_config('side')!='left'
sort = get_config("sort") or "created_utc desc"
select = f"""
SELECT
@ -215,7 +220,8 @@ def get_saved():
posts=posts,
sidebar_links=sidebar_links,
saved=True,
sort=sort.split())
sort=sort.split(),
right_handed=right_handed)
@app.route('/r/<path:subreddit>')
@ -224,6 +230,7 @@ def get_subreddit(subreddit):
connection = sqlite3.connect(config.db_file)
cursor = connection.cursor()
sidebar_links = get_sidebar_links(cursor)
right_handed = get_config('side')!='left'
sort = get_config("sort") or "created_utc asc"
select = f"""
SELECT
@ -246,7 +253,8 @@ def get_subreddit(subreddit):
title=title,
posts=posts,
sidebar_links=sidebar_links,
sort=sort.split())
sort=sort.split(),
right_handed=right_handed)
@app.route('/file/<path:filename>')
def serve_file(filename):

298
app/static/css/style.css Normal file
View File

@ -0,0 +1,298 @@
:root {
--dark: #2c2c2c;
--darker: #171717;
--light: #bfbfbf;
--confirm: #970000;
--saved: #9f9400;
--accent: #784ab4;
}
html {
height: 100%;
}
body {
background-color: var(--darker);
color: var(--light);
min-height: 100%;
margin: 0;
}
img,
video {
max-width: 100%;
width: auto;
height: auto;
display: block;
}
svg {
height: 1.5em;
width: 1.5em;
}
path {
fill: currentColor;
}
.sidebar {
display: flex;
flex-wrap: nowrap;
position: sticky;
top: 0;
left: 0;
background-color: var(--dark);
outline: 2px solid var(--light);
z-index: 1000;
}
.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);
}
.content {
display: flex;
flex-grow: 1;
flex-direction: column;
}
.header-container {
display: flex;
justify-content: space-between;
align-items: center;
margin: 0px 10px;
}
.media-div, .text-content, .button-wrapper {
padding: 0;
margin: 15px 0 0 0;
}
div.post {
background-color: var(--dark);
border: 2px solid var(--light);
border-radius: 15px;
padding: 10px;
margin-bottom: 20px;
}
div.post h3, h5 {
margin: 0;
}
/* desktop */
@media (min-aspect-ratio: 1) {
div.post, .header-container {
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) {
div.post, .header-container {
width: calc(100vw - 40px);
}
.container {
display: flex;
flex-direction: column;
}
.sidebar {
width: 100vw;
height: 50px;
flex-direction: row;
overflow-x: auto;
align-items: center;
padding: 5px, 0px;
}
.content {
align-items: center;
}
button span {
display: none;
}
}
a.no-style-link {
color: inherit;
text-decoration: inherit;
cursor: pointer;
}
.invert {
filter: invert(1);
transition: filter 0.3s;
}
.button-wrapper {
display: flex;
width: 100%;
gap: 10px;
}
.button-wrapper.flipped {
flex-direction: row-reverse;
}
.button-wrapper.gallery {
gap: 0;
}
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;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 5px;
}
.controls {
margin-top: -70px;
opacity: 0.5;
}
.controls button {
flex: 0 0 3em;
height: 3em;
margin: 5px;
}
.controls input {
flex: 1;
min-width: 0px;
}
button.confirm {
background-color: var(--confirm)
}
button.saved {
background-color: var(--saved)
}
button.gallery {
padding: 5px;
background-color: var(--darker);
border-radius: 0;
border: none;
cursor: none;
}
button.gallery.selected {
background-color: var(--light);
}
.text-content {
overflow: hidden;
transition: max-height 0.3s ease-out;
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;
}
/* The switch - the box around the slider */
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 26px;
}
/* Hide default HTML checkbox */
.switch input {
opacity: 0;
width: 0;
height: 0;
}
/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: var(--accent);
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 22px;
width: 22px;
left: 2px;
bottom: 2px;
background-color: var(--light);
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider:before {
-webkit-transform: translateX(34px);
-ms-transform: translateX(34px);
transform: translateX(34px);
}
/* Rounded sliders */
.slider.round {
border-radius: 26px;
}
.slider.round:before {
border-radius: 50%;
}

View File

@ -4,168 +4,7 @@
<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>
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
<div class="container">

View File

@ -27,247 +27,7 @@
</defs>
</svg>
<title>Reddit, but better</title>
<style>
:root {
--dark: #2c2c2c;
--darker: #171717;
--light: #bfbfbf;
--confirm: #970000;
--saved: #9f9400;
}
html {
height: 100%;
}
body {
background-color: var(--darker);
color: var(--light);
min-height: 100%;
margin: 0;
}
img,
video {
max-width: 100%;
max-height: 70vh;
width: auto;
height: auto;
display: block;
}
svg {
height: 1.5em;
width: 1.5em;
}
path {
fill: currentColor;
}
.sidebar {
display: flex;
flex-wrap: nowrap;
position: sticky;
top: 0;
left: 0;
background-color: var(--dark);
outline: 2px solid var(--light);
z-index: 1000;
}
.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);
}
.content {
display: flex;
flex-grow: 1;
flex-direction: column;
}
.header-container {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin: 0px 10px;
}
.media-div, .text-content, .button-wrapper {
padding: 0;
margin: 15px 0 0 0;
}
div.post {
background-color: var(--dark);
border: 2px solid var(--light);
border-radius: 15px;
padding: 10px;
margin-bottom: 20px;
}
div.post h3, h5 {
margin: 0;
}
/* desktop */
@media (min-aspect-ratio: 1) {
div.post, .header-container {
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) {
div.post, .header-container {
width: calc(100vw - 40px);
}
.container {
display: flex;
flex-direction: column;
}
.sidebar {
width: 100vw;
height: 50px;
flex-direction: row;
overflow-x: auto;
align-items: center;
padding: 5px, 0px;
}
.content {
align-items: center;
}
button span {
display: none;
}
}
a.no-style-link {
color: inherit;
text-decoration: inherit;
cursor: pointer;
}
.invert {
filter: invert(1);
transition: filter 0.3s;
}
.button-wrapper {
display: flex;
width: 100%;
gap: 10px;
}
.button-wrapper.gallery {
gap: 0;
}
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;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 5px;
}
.controls {
margin-top: -70px;
opacity: 0.5;
}
.controls button {
flex: 0 0 3em;
height: 3em;
margin: 5px;
}
.controls input {
flex: 1;
min-width: 0px;
}
button.confirm {
background-color: var(--confirm)
}
button.saved {
background-color: var(--saved)
}
button.gallery {
padding: 5px;
background-color: var(--darker);
border-radius: 0;
border: none;
cursor: none;
}
button.gallery.selected {
background-color: var(--light);
}
.text-content {
overflow: hidden;
transition: max-height 0.3s ease-out;
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>
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
@ -280,6 +40,12 @@
<div class="content">
<div class="header-container">
<h3>{{ title }}</h3>
<h3>
<label class="switch">
<input type="checkbox" onchange="toggleSide(this)" {% if right_handed %}checked{% endif %}>
<span class="slider round"></span>
</label>
</h3>
<h3>
<span onclick="changeSortKey()">{{ sort[0] }}</span>
<span onclick="changeSortDir()">{{ sort[1] }}</span>
@ -315,20 +81,7 @@
{{ post.body|safe }}
</div>
{% endif %}
<span class="button-wrapper">
<button type="button" name="comments" onpointerdown='commentsDown(this, "{{ post.permalink }}")'
onpointerup='commentsUp(this, "{{ post.permalink }}")'>
<svg viewBox="0 0 24 24">
<use xlink:href="#icon-comments"></use>
</svg>
<span>Comments</span>
</button>
<button type="button" name="save" onclick='save(this, "{{ post.permalink }}")' {% if saved %}class='saved' {% endif %}>
<svg viewBox="0 0 24 24">
<use xlink:href="#icon-save"></use>
</svg>
<span>Save</span>
</button>
<span class="button-wrapper{% if right_handed %} flipped{% endif %}">
{% if not saved %}
<button type="button" name="hide" onclick='hide(this, "{{ post.permalink }}")'>
<svg viewBox="0 0 24 24">
@ -337,6 +90,19 @@
<span>Hide</span>
</button>
{% endif %}
<button type="button" name="save" onclick='save(this, "{{ post.permalink }}")' {% if saved %}class='saved' {% endif %}>
<svg viewBox="0 0 24 24">
<use xlink:href="#icon-save"></use>
</svg>
<span>Save</span>
</button>
<button type="button" name="comments" onpointerdown='commentsDown(this, "{{ post.permalink }}")'
onpointerup='commentsUp(this, "{{ post.permalink }}")'>
<svg viewBox="0 0 24 24">
<use xlink:href="#icon-comments"></use>
</svg>
<span>Comments</span>
</button>
</span>
</div>
{% endfor %}
@ -604,6 +370,23 @@
setTimeout(() => {window.location.href = window.location.href;}, 1000);
});
}
function toggleSide(checkbox) {
newSide = "left";
if (checkbox.checked) {
newSide = "right";
}
params = {
key: "side",
value: newSide
};
params = new URLSearchParams(params).toString()
fetch("/config?" + params, {
method: 'POST'
}).then(() => {
setTimeout(() => {window.location.href = window.location.href;}, 1000);
});
}
</script>
</body>