mirror of
https://codeberg.org/rimu/pyfedi
synced 2025-01-23 19:36:56 -08:00
masonry tile for image communities
This commit is contained in:
parent
f140d0369e
commit
af98706610
13 changed files with 351 additions and 28 deletions
|
@ -47,14 +47,14 @@ class EditCommunityForm(FlaskForm):
|
||||||
icon_file = FileField(_('Icon image'))
|
icon_file = FileField(_('Icon image'))
|
||||||
banner_file = FileField(_('Banner image'))
|
banner_file = FileField(_('Banner image'))
|
||||||
rules = TextAreaField(_l('Rules'))
|
rules = TextAreaField(_l('Rules'))
|
||||||
nsfw = BooleanField('Porn community')
|
nsfw = BooleanField(_l('Porn community'))
|
||||||
local_only = BooleanField('Only accept posts from current instance')
|
local_only = BooleanField(_l('Only accept posts from current instance'))
|
||||||
restricted_to_mods = BooleanField('Only moderators can post')
|
restricted_to_mods = BooleanField(_l('Only moderators can post'))
|
||||||
new_mods_wanted = BooleanField('New moderators wanted')
|
new_mods_wanted = BooleanField(_l('New moderators wanted'))
|
||||||
show_home = BooleanField('Posts show on home page')
|
show_home = BooleanField(_l('Posts show on home page'))
|
||||||
show_popular = BooleanField('Posts can be popular')
|
show_popular = BooleanField(_l('Posts can be popular'))
|
||||||
show_all = BooleanField('Posts show in All list')
|
show_all = BooleanField(_l('Posts show in All list'))
|
||||||
low_quality = BooleanField("Low quality / toxic - upvotes in here don't add to reputation")
|
low_quality = BooleanField(_l("Low quality / toxic - upvotes in here don't add to reputation"))
|
||||||
options = [(-1, _l('Forever')),
|
options = [(-1, _l('Forever')),
|
||||||
(7, _l('1 week')),
|
(7, _l('1 week')),
|
||||||
(14, _l('2 weeks')),
|
(14, _l('2 weeks')),
|
||||||
|
@ -69,6 +69,10 @@ class EditCommunityForm(FlaskForm):
|
||||||
]
|
]
|
||||||
content_retention = SelectField(_l('Retain content'), choices=options, default=1, coerce=int)
|
content_retention = SelectField(_l('Retain content'), choices=options, default=1, coerce=int)
|
||||||
topic = SelectField(_l('Topic'), coerce=int, validators=[Optional()])
|
topic = SelectField(_l('Topic'), coerce=int, validators=[Optional()])
|
||||||
|
layouts = [('', _l('List')),
|
||||||
|
('masonry', _l('Masonry')),
|
||||||
|
('masonry_wide', _l('Wide masonry'))]
|
||||||
|
default_layout = SelectField(_l('Layout'), coerce=str, choices=layouts, validators=[Optional()])
|
||||||
submit = SubmitField(_l('Save'))
|
submit = SubmitField(_l('Save'))
|
||||||
|
|
||||||
def validate(self, extra_validators=None):
|
def validate(self, extra_validators=None):
|
||||||
|
@ -93,8 +97,8 @@ class EditTopicForm(FlaskForm):
|
||||||
class EditUserForm(FlaskForm):
|
class EditUserForm(FlaskForm):
|
||||||
about = TextAreaField(_l('Bio'), validators=[Optional(), Length(min=3, max=5000)])
|
about = TextAreaField(_l('Bio'), validators=[Optional(), Length(min=3, max=5000)])
|
||||||
matrix_user_id = StringField(_l('Matrix User ID'), validators=[Optional(), Length(max=255)])
|
matrix_user_id = StringField(_l('Matrix User ID'), validators=[Optional(), Length(max=255)])
|
||||||
profile_file = FileField(_('Avatar image'))
|
profile_file = FileField(_l('Avatar image'))
|
||||||
banner_file = FileField(_('Top banner image'))
|
banner_file = FileField(_l('Top banner image'))
|
||||||
bot = BooleanField(_l('This profile is a bot'))
|
bot = BooleanField(_l('This profile is a bot'))
|
||||||
newsletter = BooleanField(_l('Subscribe to email newsletter'))
|
newsletter = BooleanField(_l('Subscribe to email newsletter'))
|
||||||
ignore_bots = BooleanField(_l('Hide posts by bots'))
|
ignore_bots = BooleanField(_l('Hide posts by bots'))
|
||||||
|
|
|
@ -241,6 +241,7 @@ def admin_community_edit(community_id):
|
||||||
community.low_quality = form.low_quality.data
|
community.low_quality = form.low_quality.data
|
||||||
community.content_retention = form.content_retention.data
|
community.content_retention = form.content_retention.data
|
||||||
community.topic_id = form.topic.data if form.topic.data != 0 else None
|
community.topic_id = form.topic.data if form.topic.data != 0 else None
|
||||||
|
community.default_layout = form.default_layout.data
|
||||||
icon_file = request.files['icon_file']
|
icon_file = request.files['icon_file']
|
||||||
if icon_file and icon_file.filename != '':
|
if icon_file and icon_file.filename != '':
|
||||||
if community.icon_id:
|
if community.icon_id:
|
||||||
|
@ -276,6 +277,7 @@ def admin_community_edit(community_id):
|
||||||
form.low_quality.data = community.low_quality
|
form.low_quality.data = community.low_quality
|
||||||
form.content_retention.data = community.content_retention
|
form.content_retention.data = community.content_retention
|
||||||
form.topic.data = community.topic_id if community.topic_id else None
|
form.topic.data = community.topic_id if community.topic_id else None
|
||||||
|
form.default_layout.data = community.default_layout
|
||||||
return render_template('admin/edit_community.html', title=_('Edit community'), form=form, community=community,
|
return render_template('admin/edit_community.html', title=_('Edit community'), form=form, community=community,
|
||||||
moderating_communities=moderating_communities(current_user.get_id()),
|
moderating_communities=moderating_communities(current_user.get_id()),
|
||||||
joined_communities=joined_communities(current_user.get_id())
|
joined_communities=joined_communities(current_user.get_id())
|
||||||
|
|
|
@ -105,6 +105,8 @@ def show_community(community: Community):
|
||||||
|
|
||||||
page = request.args.get('page', 1, type=int)
|
page = request.args.get('page', 1, type=int)
|
||||||
sort = request.args.get('sort', '' if current_user.is_anonymous else current_user.default_sort)
|
sort = request.args.get('sort', '' if current_user.is_anonymous else current_user.default_sort)
|
||||||
|
low_bandwidth = request.cookies.get('low_bandwidth', '0') == '1'
|
||||||
|
post_layout = request.args.get('layout', community.default_layout if not low_bandwidth else '')
|
||||||
|
|
||||||
# If nothing has changed since their last visit, return HTTP 304
|
# If nothing has changed since their last visit, return HTTP 304
|
||||||
current_etag = f"{community.id}{sort}_{hash(community.last_active)}"
|
current_etag = f"{community.id}{sort}_{hash(community.last_active)}"
|
||||||
|
@ -138,7 +140,12 @@ def show_community(community: Community):
|
||||||
posts = posts.order_by(desc(Post.posted_at))
|
posts = posts.order_by(desc(Post.posted_at))
|
||||||
elif sort == 'active':
|
elif sort == 'active':
|
||||||
posts = posts.order_by(desc(Post.last_active))
|
posts = posts.order_by(desc(Post.last_active))
|
||||||
posts = posts.paginate(page=page, per_page=100, error_out=False)
|
per_page = 100
|
||||||
|
if post_layout == 'masonry':
|
||||||
|
per_page = 200
|
||||||
|
elif post_layout == 'masonry_wide':
|
||||||
|
per_page = 300
|
||||||
|
posts = posts.paginate(page=page, per_page=per_page, error_out=False)
|
||||||
|
|
||||||
if community.topic_id:
|
if community.topic_id:
|
||||||
related_communities = Community.query.filter_by(topic_id=community.topic_id).\
|
related_communities = Community.query.filter_by(topic_id=community.topic_id).\
|
||||||
|
@ -159,11 +166,11 @@ def show_community(community: Community):
|
||||||
og_image=og_image, POST_TYPE_IMAGE=POST_TYPE_IMAGE, POST_TYPE_LINK=POST_TYPE_LINK, SUBSCRIPTION_PENDING=SUBSCRIPTION_PENDING,
|
og_image=og_image, POST_TYPE_IMAGE=POST_TYPE_IMAGE, POST_TYPE_LINK=POST_TYPE_LINK, SUBSCRIPTION_PENDING=SUBSCRIPTION_PENDING,
|
||||||
SUBSCRIPTION_MEMBER=SUBSCRIPTION_MEMBER, SUBSCRIPTION_OWNER=SUBSCRIPTION_OWNER, SUBSCRIPTION_MODERATOR=SUBSCRIPTION_MODERATOR,
|
SUBSCRIPTION_MEMBER=SUBSCRIPTION_MEMBER, SUBSCRIPTION_OWNER=SUBSCRIPTION_OWNER, SUBSCRIPTION_MODERATOR=SUBSCRIPTION_MODERATOR,
|
||||||
etag=f"{community.id}{sort}_{hash(community.last_active)}", related_communities=related_communities,
|
etag=f"{community.id}{sort}_{hash(community.last_active)}", related_communities=related_communities,
|
||||||
next_url=next_url, prev_url=prev_url, low_bandwidth=request.cookies.get('low_bandwidth', '0') == '1',
|
next_url=next_url, prev_url=prev_url, low_bandwidth=low_bandwidth,
|
||||||
rss_feed=f"https://{current_app.config['SERVER_NAME']}/community/{community.link()}/feed", rss_feed_name=f"{community.title} posts on PieFed",
|
rss_feed=f"https://{current_app.config['SERVER_NAME']}/community/{community.link()}/feed", rss_feed_name=f"{community.title} posts on PieFed",
|
||||||
content_filters=content_filters, moderating_communities=moderating_communities(current_user.get_id()),
|
content_filters=content_filters, moderating_communities=moderating_communities(current_user.get_id()),
|
||||||
joined_communities=joined_communities(current_user.get_id()), sort=sort,
|
joined_communities=joined_communities(current_user.get_id()), sort=sort,
|
||||||
inoculation=inoculation[randint(0, len(inoculation) - 1)])
|
inoculation=inoculation[randint(0, len(inoculation) - 1)], post_layout=post_layout)
|
||||||
|
|
||||||
|
|
||||||
# RSS feed of the community
|
# RSS feed of the community
|
||||||
|
|
|
@ -146,6 +146,7 @@ class Community(db.Model):
|
||||||
private_key = db.Column(db.Text)
|
private_key = db.Column(db.Text)
|
||||||
content_retention = db.Column(db.Integer, default=-1)
|
content_retention = db.Column(db.Integer, default=-1)
|
||||||
topic_id = db.Column(db.Integer, db.ForeignKey('topic.id'), index=True)
|
topic_id = db.Column(db.Integer, db.ForeignKey('topic.id'), index=True)
|
||||||
|
default_layout = db.Column(db.String(15))
|
||||||
|
|
||||||
ap_id = db.Column(db.String(255), index=True)
|
ap_id = db.Column(db.String(255), index=True)
|
||||||
ap_profile_id = db.Column(db.String(255), index=True)
|
ap_profile_id = db.Column(db.String(255), index=True)
|
||||||
|
|
|
@ -597,6 +597,83 @@ fieldset legend {
|
||||||
font-size: 80%;
|
font-size: 80%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.post_list_masonry, .post_list_masonry_wide {
|
||||||
|
-webkit-column-count: 2;
|
||||||
|
-moz-column-count: 2;
|
||||||
|
column-count: 2;
|
||||||
|
-webkit-column-gap: 5px;
|
||||||
|
-moz-column-gap: 5px;
|
||||||
|
column-gap: 5px;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
@media (min-width: 992px) {
|
||||||
|
.post_list_masonry, .post_list_masonry_wide {
|
||||||
|
-webkit-column-count: 4;
|
||||||
|
-moz-column-count: 4;
|
||||||
|
column-count: 4;
|
||||||
|
-webkit-column-gap: 5px;
|
||||||
|
-moz-column-gap: 5px;
|
||||||
|
column-gap: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.post_list_masonry .post_teaser, .post_list_masonry_wide .post_teaser {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.post_list_masonry .post_teaser img, .post_list_masonry_wide .post_teaser img {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
.post_list_masonry .post_teaser .masonry_info, .post_list_masonry_wide .post_teaser .masonry_info {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.2);
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.post_list_masonry .post_teaser .masonry_info p, .post_list_masonry_wide .post_teaser .masonry_info p {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.post_list_masonry .post_teaser .masonry_info p a, .post_list_masonry_wide .post_teaser .masonry_info p a {
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
line-height: 40px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1280px) {
|
||||||
|
.post_list_masonry .post_teaser .masonry_info p a, .post_list_masonry_wide .post_teaser .masonry_info p a {
|
||||||
|
line-height: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.post_list_masonry .post_teaser .masonry_info_no_image, .post_list_masonry_wide .post_teaser .masonry_info_no_image {
|
||||||
|
background-color: rgba(0, 0, 0, 0.2);
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.post_list_masonry .post_teaser .masonry_info_no_image p, .post_list_masonry_wide .post_teaser .masonry_info_no_image p {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.post_list_masonry .post_teaser .masonry_info_no_image p a, .post_list_masonry_wide .post_teaser .masonry_info_no_image p a {
|
||||||
|
color: var(--bs-body-color);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 992px) {
|
||||||
|
.post_list_masonry_wide {
|
||||||
|
-webkit-column-count: 5;
|
||||||
|
-moz-column-count: 5;
|
||||||
|
column-count: 5;
|
||||||
|
-webkit-column-gap: 5px;
|
||||||
|
-moz-column-gap: 5px;
|
||||||
|
column-gap: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 992px) {
|
||||||
|
.layout_switcher {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.url_thumbnail {
|
.url_thumbnail {
|
||||||
float: right;
|
float: right;
|
||||||
margin-top: -6px;
|
margin-top: -6px;
|
||||||
|
|
|
@ -218,6 +218,86 @@ nav, etc which are used site-wide */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.post_list_masonry, .post_list_masonry_wide {
|
||||||
|
-webkit-column-count: 2;
|
||||||
|
-moz-column-count: 2;
|
||||||
|
column-count: 2;
|
||||||
|
-webkit-column-gap: 5px;
|
||||||
|
-moz-column-gap: 5px;
|
||||||
|
column-gap: 5px;
|
||||||
|
clear: both;
|
||||||
|
|
||||||
|
@include breakpoint(tablet) {
|
||||||
|
-webkit-column-count: 4;
|
||||||
|
-moz-column-count: 4;
|
||||||
|
column-count: 4;
|
||||||
|
-webkit-column-gap: 5px;
|
||||||
|
-moz-column-gap: 5px;
|
||||||
|
column-gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post_teaser {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
position: relative;
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.masonry_info {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.2);
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
p {
|
||||||
|
margin-bottom: 0;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
line-height: 40px;
|
||||||
|
@include breakpoint(laptop) {
|
||||||
|
line-height: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.masonry_info_no_image {
|
||||||
|
background-color: rgba(0, 0, 0, 0.2);
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
p {
|
||||||
|
margin-bottom: 0;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--bs-body-color);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.post_list_masonry_wide {
|
||||||
|
@include breakpoint(tablet) {
|
||||||
|
-webkit-column-count: 5;
|
||||||
|
-moz-column-count: 5;
|
||||||
|
column-count: 5;
|
||||||
|
-webkit-column-gap: 5px;
|
||||||
|
-moz-column-gap: 5px;
|
||||||
|
column-gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout_switcher {
|
||||||
|
@include breakpoint(tablet) {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.url_thumbnail {
|
.url_thumbnail {
|
||||||
float: right;
|
float: right;
|
||||||
margin-top: -6px;
|
margin-top: -6px;
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
{{ render_field(form.low_quality) }}
|
{{ render_field(form.low_quality) }}
|
||||||
{{ render_field(form.content_retention) }}
|
{{ render_field(form.content_retention) }}
|
||||||
{{ render_field(form.topic) }}
|
{{ render_field(form.topic) }}
|
||||||
|
{{ render_field(form.default_layout) }}
|
||||||
{% if not community.is_local() %}
|
{% if not community.is_local() %}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -94,7 +94,7 @@
|
||||||
<!-- Page content -->
|
<!-- Page content -->
|
||||||
{% block navbar %}
|
{% block navbar %}
|
||||||
<nav class="navbar navbar-expand-lg">
|
<nav class="navbar navbar-expand-lg">
|
||||||
<div class="container-lg">
|
<div class="{{ 'container-lg' if post_layout != 'masonry_wide' else 'container-fluid' }}">
|
||||||
<a class="navbar-brand" href="/">{% if not low_bandwidth %}<img src="/static/images/logo2.png" alt="Logo" width="50" height="50" />{% endif %}{{ g.site.name }}</a>
|
<a class="navbar-brand" href="/">{% if not low_bandwidth %}<img src="/static/images/logo2.png" alt="Logo" width="50" height="50" />{% endif %}{{ g.site.name }}</a>
|
||||||
{% if current_user.is_authenticated %}
|
{% if current_user.is_authenticated %}
|
||||||
<a class="nav-link d-lg-none" href="/notifications" aria-label="{{ _('Notifications') }}">
|
<a class="nav-link d-lg-none" href="/notifications" aria-label="{{ _('Notifications') }}">
|
||||||
|
@ -191,7 +191,7 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div id="outer_container" class="container-lg flex-shrink-0">
|
<div id="outer_container" class="{{ 'container-lg' if post_layout != 'masonry_wide' else 'container-fluid' }} flex-shrink-0">
|
||||||
{% with messages = get_flashed_messages(with_categories=True) %}
|
{% with messages = get_flashed_messages(with_categories=True) %}
|
||||||
{% if messages %}
|
{% if messages %}
|
||||||
{% for category, message in messages %}
|
{% for category, message in messages %}
|
||||||
|
|
|
@ -15,3 +15,16 @@
|
||||||
{{ _('Active') }}
|
{{ _('Active') }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
{% if post_layout != '' %}
|
||||||
|
<div class="btn-group mt-1 mb-2 layout_switcher">
|
||||||
|
<a href="?layout=list" class="btn {{ 'btn-primary' if post_layout == '' or post_layout == 'list' else 'btn-outline-secondary' }}" rel="nofollow">
|
||||||
|
{{ _('List') }}
|
||||||
|
</a>
|
||||||
|
<a href="?layout=masonry" class="btn {{ 'btn-primary' if post_layout == 'masonry' else 'btn-outline-secondary' }}" rel="nofollow">
|
||||||
|
{{ _('Tile') }}
|
||||||
|
</a>
|
||||||
|
<a href="?layout=masonry_wide" class="btn {{ 'btn-primary' if post_layout == 'masonry_wide' else 'btn-outline-secondary' }}" rel="nofollow">
|
||||||
|
{{ _('Wide tile') }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
|
@ -64,6 +64,15 @@
|
||||||
</h1>
|
</h1>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% include "community/_community_nav.html" %}
|
{% include "community/_community_nav.html" %}
|
||||||
|
{% if post_layout == 'masonry' or post_layout == 'masonry_wide' %}
|
||||||
|
<div class="post_list_{{ post_layout }}">
|
||||||
|
{% for post in posts %}
|
||||||
|
{% include 'post/_post_teaser_masonry.html' %}
|
||||||
|
{% else %}
|
||||||
|
<p>{{ _('No posts in this community yet.') }}</p>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
<div class="post_list">
|
<div class="post_list">
|
||||||
{% for post in posts %}
|
{% for post in posts %}
|
||||||
{% include 'post/_post_teaser.html' %}
|
{% include 'post/_post_teaser.html' %}
|
||||||
|
@ -71,6 +80,7 @@
|
||||||
<p>{{ _('No posts in this community yet.') }}</p>
|
<p>{{ _('No posts in this community yet.') }}</p>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<nav aria-label="Pagination" class="mt-4">
|
<nav aria-label="Pagination" class="mt-4">
|
||||||
{% if prev_url %}
|
{% if prev_url %}
|
||||||
|
|
|
@ -16,15 +16,15 @@
|
||||||
<div class="thumbnail">
|
<div class="thumbnail">
|
||||||
{% if post.type == POST_TYPE_LINK %}
|
{% if post.type == POST_TYPE_LINK %}
|
||||||
<a href="{{ post.url }}" rel="nofollow ugc" target="_blank" aria-label="{{ _('Read article') }}"><img src="{{ post.image.thumbnail_url() }}"
|
<a href="{{ post.url }}" rel="nofollow ugc" target="_blank" aria-label="{{ _('Read article') }}"><img src="{{ post.image.thumbnail_url() }}"
|
||||||
alt="{{ post.image.alt_text if post.image.alt_text else '' }}" height="50" /></a>
|
alt="{{ post.image.alt_text if post.image.alt_text else '' }}" height="50" loading="lazy" /></a>
|
||||||
{% elif post.type == POST_TYPE_IMAGE %}
|
{% elif post.type == POST_TYPE_IMAGE %}
|
||||||
{% if post.image_id %}
|
{% if post.image_id %}
|
||||||
<a href="{{ post.image.view_url() }}" rel="nofollow ugc" target="_blank"><img src="{{ post.image.thumbnail_url() }}"
|
<a href="{{ post.image.view_url() }}" rel="nofollow ugc" target="_blank"><img src="{{ post.image.thumbnail_url() }}"
|
||||||
alt="{{ post.image.alt_text if post.image.alt_text else '' }}" height="50" /></a>
|
alt="{{ post.image.alt_text if post.image.alt_text else '' }}" height="50" loading="lazy" /></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="{{ url_for('activitypub.post_ap', post_id=post.id) }}"><img src="{{ post.image.thumbnail_url() }}"
|
<a href="{{ url_for('activitypub.post_ap', post_id=post.id) }}"><img src="{{ post.image.thumbnail_url() }}"
|
||||||
alt="{{ post.image.alt_text if post.image.alt_text else '' }}" height="50" /></a>
|
alt="{{ post.image.alt_text if post.image.alt_text else '' }}" height="50" loading="lazy" /></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -65,7 +65,5 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
98
app/templates/post/_post_teaser_masonry.html
Normal file
98
app/templates/post/_post_teaser_masonry.html
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
{% set content_blocked = post.blocked_by_content_filter(content_filters) %}
|
||||||
|
{% if content_blocked and content_blocked == '-1' %}
|
||||||
|
{# do nothing - blocked by keyword filter #}
|
||||||
|
{% else %}
|
||||||
|
<div class="post_teaser{{ ' reported' if post.reports and current_user.is_authenticated and post.community.is_moderator() }}{{ ' blocked' if content_blocked }}"
|
||||||
|
{% if content_blocked %} title="{{ _('Filtered: ') }}{{ content_blocked }}"{% endif %}>
|
||||||
|
{% if post.image_id %}
|
||||||
|
{% if post_layout == 'masonry' or low_bandwidth %}
|
||||||
|
{% set thumbnail = post.image.thumbnail_url() %}
|
||||||
|
{% elif post_layout == 'masonry_wide' %}
|
||||||
|
{% set thumbnail = post.image.view_url() %}
|
||||||
|
{% endif %}
|
||||||
|
<div class="masonry_thumb">
|
||||||
|
{% if post.type == POST_TYPE_LINK %}
|
||||||
|
<a href="{{ post.url }}" rel="nofollow ugc" target="_blank" aria-label="{{ _('Read article') }}"><img src="{{ post.image.thumbnail_url() }}"
|
||||||
|
alt="{{ post.image.alt_text if post.image.alt_text else '' }}" loading="lazy" /></a>
|
||||||
|
{% elif post.type == POST_TYPE_IMAGE %}
|
||||||
|
<a href="{{ post.image.view_url() }}" rel="nofollow ugc" target="_blank"><img src="{{ post.image.thumbnail_url() }}"
|
||||||
|
alt="{{ post.image.alt_text if post.image.alt_text else '' }}" loading="lazy" /></a>
|
||||||
|
{% else %}
|
||||||
|
<a href="{{ url_for('activitypub.post_ap', post_id=post.id) }}"><img src="{{ post.image.thumbnail_url() }}"
|
||||||
|
alt="{{ post.image.alt_text if post.image.alt_text else '' }}" loading="lazy" /></a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="masonry_info">
|
||||||
|
<p><a href="{{ url_for('activitypub.post_ap', post_id=post.id) }}">{{ post.title|shorten(25) }}</a></p>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="masonry_info_no_image">
|
||||||
|
<p><a href="{{ url_for('activitypub.post_ap', post_id=post.id) }}">{{ post.title }}</a></p>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<!--
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="row main_row">
|
||||||
|
<div class="col">
|
||||||
|
<h3 class="post_teaser_title">
|
||||||
|
<div class="voting_buttons">
|
||||||
|
{% include "post/_post_voting_buttons.html" %}
|
||||||
|
</div>
|
||||||
|
{% if post.image_id and not low_bandwidth %}
|
||||||
|
<div class="thumbnail">
|
||||||
|
{% if post.type == POST_TYPE_LINK %}
|
||||||
|
<a href="{{ post.url }}" rel="nofollow ugc" target="_blank" aria-label="{{ _('Read article') }}"><img src="{{ post.image.thumbnail_url() }}"
|
||||||
|
alt="{{ post.image.alt_text if post.image.alt_text else '' }}" height="50" /></a>
|
||||||
|
{% elif post.type == POST_TYPE_IMAGE %}
|
||||||
|
{% if post.image_id %}
|
||||||
|
<a href="{{ post.image.view_url() }}" rel="nofollow ugc" target="_blank"><img src="{{ post.image.thumbnail_url() }}"
|
||||||
|
alt="{{ post.image.alt_text if post.image.alt_text else '' }}" height="50" /></a>
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
<a href="{{ url_for('activitypub.post_ap', post_id=post.id) }}"><img src="{{ post.image.thumbnail_url() }}"
|
||||||
|
alt="{{ post.image.alt_text if post.image.alt_text else '' }}" height="50" /></a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<a href="{{ url_for('activitypub.post_ap', post_id=post.id, sort='new' if sort == 'active' else None) }}" class="post_teaser_title_a">{{ post.title }}</a>
|
||||||
|
{% if post.type == POST_TYPE_IMAGE %}<span class="fe fe-image"> </span>{% endif %}
|
||||||
|
{% if post.type == POST_TYPE_LINK and post.domain_id %}
|
||||||
|
{% if post.url and 'youtube.com' in post.url %}
|
||||||
|
<span class="fe fe-video"></span>
|
||||||
|
{% endif %}
|
||||||
|
<a href="{{ post.url }}" rel="nofollow ugc" target="_blank" class="post_link">
|
||||||
|
<img src="/static/images/external_link_black.svg" class="external_link_icon" alt="External link" />
|
||||||
|
</a>
|
||||||
|
<span class="domain_link">(<a href="/d/{{ post.domain_id }}">{{ post.domain.name }}</a>)</span>
|
||||||
|
{% endif %}
|
||||||
|
{% if post.reports and current_user.is_authenticated and post.community.is_moderator(current_user) %}
|
||||||
|
<span class="red fe fe-report" title="{{ _('Reported. Check post for issues.') }}"></span>
|
||||||
|
{% endif %}
|
||||||
|
</h3>
|
||||||
|
<span class="small">{% if show_post_community %}<strong><a href="/c/{{ post.community.link() }}">c/{{ post.community.name }}</a></strong>{% endif %}
|
||||||
|
by {{ render_username(post.author) }} {{ moment(post.last_active if sort == 'active' else post.posted_at).fromNow() }}</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="row utilities_row">
|
||||||
|
<div class="col-6">
|
||||||
|
<a href="{{ url_for('activitypub.post_ap', post_id=post.id, sort='new' if sort == 'active' else None, _anchor='post_replies') }}" aria-label="{{ _('View comments') }}"><span class="fe fe-reply"></span></a>
|
||||||
|
<a href="{{ url_for('activitypub.post_ap', post_id=post.id, sort='new' if sort == 'active' else None, _anchor='post_replies') }}">{{ post.reply_count }}</a>
|
||||||
|
{% if post.type == POST_TYPE_IMAGE %}
|
||||||
|
{% if post.image_id %}
|
||||||
|
<a href="{{ post.image.view_url() }}" rel="nofollow ugc" class="preview_image" aria-label="{{ _('View image') }}"><span class="fe fe-magnify"></span></a>
|
||||||
|
{% else %}
|
||||||
|
<a href="{{ post.url }}" rel="nofollow ugc" class="preview_image" target="_blank" aria-label="{{ _('View image') }}"><span class="fe fe-magnify"></span></a>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="col-2"><a href="{{ url_for('post.post_options', post_id=post.id) }}" rel="nofollow" aria-label="{{ _('Options') }}"><span class="fe fe-options" title="Options"> </span></a></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
-->
|
||||||
|
{% endif %}
|
32
migrations/versions/a4be1b198b0f_community_default_layout.py
Normal file
32
migrations/versions/a4be1b198b0f_community_default_layout.py
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
"""community default layout
|
||||||
|
|
||||||
|
Revision ID: a4be1b198b0f
|
||||||
|
Revises: 6b4774eb6349
|
||||||
|
Create Date: 2024-01-21 14:22:02.450650
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = 'a4be1b198b0f'
|
||||||
|
down_revision = '6b4774eb6349'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
with op.batch_alter_table('community', schema=None) as batch_op:
|
||||||
|
batch_op.add_column(sa.Column('default_layout', sa.String(length=15), nullable=True))
|
||||||
|
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
with op.batch_alter_table('community', schema=None) as batch_op:
|
||||||
|
batch_op.drop_column('default_layout')
|
||||||
|
|
||||||
|
# ### end Alembic commands ###
|
Loading…
Add table
Reference in a new issue