234 lines
12 KiB
HTML
Raw Normal View History

2026-05-10 09:08:12 +02:00
{% extends "base.html" %}
{% block extra_head %}
<link rel="stylesheet" href="/static/css/feed.css">
2026-05-12 13:08:38 +02:00
<link rel="stylesheet" href="/static/css/sidebar.css">
2026-05-10 09:08:12 +02:00
{% endblock %}
{% block content %}
2026-05-11 05:30:51 +02:00
<h1 class="sr-only">Feed</h1>
2026-05-10 09:08:12 +02:00
<div class="feed-layout">
2026-05-12 13:08:38 +02:00
<aside class="sidebar-card">
<div class="sidebar-heading">Topics</div>
<div class="sidebar-nav">
<a href="/feed" class="sidebar-link {% if not current_topic %}active{% endif %}">
2026-05-12 15:07:34 +02:00
<span class="icon">&#x1F4CB;</span>
2026-05-10 09:08:12 +02:00
All
</a>
2026-05-12 13:08:38 +02:00
<a href="/feed?topic=devlog" class="sidebar-link {% if current_topic == 'devlog' %}active{% endif %}" data-topic="devlog">
2026-05-12 15:07:34 +02:00
<span class="icon">&#x1F4DD;</span>
2026-05-10 09:08:12 +02:00
Devlog
</a>
2026-05-12 13:08:38 +02:00
<a href="/feed?topic=showcase" class="sidebar-link {% if current_topic == 'showcase' %}active{% endif %}" data-topic="showcase">
2026-05-12 15:07:34 +02:00
<span class="icon">&#x2728;</span>
2026-05-10 09:08:12 +02:00
Showcase
</a>
2026-05-12 13:08:38 +02:00
<a href="/feed?topic=question" class="sidebar-link {% if current_topic == 'question' %}active{% endif %}" data-topic="question">
2026-05-12 15:07:34 +02:00
<span class="icon">&#x2753;</span>
2026-05-10 09:08:12 +02:00
Question
</a>
2026-05-12 13:08:38 +02:00
<a href="/feed?topic=rant" class="sidebar-link {% if current_topic == 'rant' %}active{% endif %}" data-topic="rant">
2026-05-12 15:07:34 +02:00
<span class="icon">&#x1F4A2;</span>
2026-05-10 09:08:12 +02:00
Rant
</a>
2026-05-12 13:08:38 +02:00
<a href="/feed?topic=fun" class="sidebar-link {% if current_topic == 'fun' %}active{% endif %}" data-topic="fun">
2026-05-12 15:07:34 +02:00
<span class="icon">&#x1F3AE;</span>
2026-05-10 09:08:12 +02:00
Fun
</a>
2026-05-12 13:08:38 +02:00
<a href="/feed?topic=signals" class="sidebar-link {% if current_topic == 'signals' %}active{% endif %}" data-topic="signals">
2026-05-12 15:07:34 +02:00
<span class="icon">&#x1F4E1;</span>
2026-05-11 07:02:06 +02:00
Signals
</a>
2026-05-10 09:08:12 +02:00
</div>
</aside>
<div class="feed-main">
<div class="feed-nav">
2026-05-16 03:29:43 +02:00
<a href="/feed?tab=all" class="feed-nav-btn {% if current_tab == 'all' or not current_tab %}active{% endif %}"><span class="icon">&#x1F4CB;</span> All</a>
<a href="/feed?tab=trending" class="feed-nav-btn {% if current_tab == 'trending' %}active{% endif %}"><span class="icon">&#x1F525;</span> Trending</a>
<a href="/feed?tab=recent" class="feed-nav-btn {% if current_tab == 'recent' %}active{% endif %}"><span class="icon">&#x1F550;</span> Recent</a>
<a href="/feed?tab=following" class="feed-nav-btn {% if current_tab == 'following' %}active{% endif %}"><span class="icon">&#x1F465;</span> Following</a>
2026-05-10 09:08:12 +02:00
<div class="feed-nav-actions">
2026-05-13 21:17:57 +02:00
<button class="btn-ghost btn-icon" title="Refresh" onclick="window.location.reload()">&#x21BB;</button>
<button class="btn-ghost btn-icon" title="Notifications" onclick="window.location.href='/notifications'">&#x1F514;</button>
2026-05-10 09:08:12 +02:00
</div>
</div>
<div class="feed-posts">
{% for item in posts %}
<article class="post-card fade-in">
<div class="post-header">
2026-05-11 05:30:51 +02:00
{% set _user = item.author %}{% set _size = 32 %}{% set _size_class = "sm" %}{% include "_avatar_link.html" %}
2026-05-10 21:33:53 +02:00
<div class="post-author-wrap">
2026-05-11 05:30:51 +02:00
<a href="/profile/{{ item.author['username'] if item.author else '#' }}" class="post-author-link">{{ item.author['username'] if item.author else 'Unknown' }}</a>
2026-05-10 21:33:53 +02:00
{% if item.author and item.author.get('role') %}
<span class="post-author-role">{{ item.author['role'] }}</span>
{% endif %}
2026-05-10 09:08:12 +02:00
</div>
<span class="post-time">{{ item.time_ago }}</span>
</div>
<div class="post-topic">
<span class="badge badge-{{ item.post['topic'] }}">{{ item.post['topic'] }}</span>
</div>
{% if item.post.get('title') %}
2026-05-16 02:31:11 +02:00
<a href="/posts/{{ item.post['slug'] or item.post['uid'] }}" class="post-title-link">
<h3 class="post-title">{{ item.post['title'] }}</h3>
</a>
2026-05-10 09:08:12 +02:00
{% endif %}
2026-05-16 02:31:11 +02:00
<div class="post-content rendered-content" data-render onclick="if (!event.target.closest('a')) window.location.href='/posts/{{ item.post['slug'] or item.post['uid'] }}'">{{ item.post['content'][:300] }}{% if item.post['content']|length > 300 %}...{% endif %}</div>
2026-05-10 09:08:12 +02:00
2026-05-12 15:07:34 +02:00
{% if item.attachments %}
{% include "_attachment_display.html" %}
{% endif %}
2026-05-10 09:08:12 +02:00
<div class="post-actions">
2026-05-16 02:31:11 +02:00
<div class="post-votes">
<form method="POST" action="/votes/post/{{ item.post['uid'] }}" class="inline-form">
<input type="hidden" name="value" value="1">
<button type="submit" class="post-action-btn vote-up" data-vote="1" data-target="{{ item.post['uid'] }}" data-type="post">+</button>
</form>
<span class="post-vote-count">{{ item.post.get('stars', 0) }}</span>
<form method="POST" action="/votes/post/{{ item.post['uid'] }}" class="inline-form">
<input type="hidden" name="value" value="-1">
<button type="submit" class="post-action-btn vote-down" data-vote="-1" data-target="{{ item.post['uid'] }}" data-type="post">−</button>
</form>
</div>
2026-05-11 20:49:45 +02:00
<a href="/posts/{{ item.post['slug'] or item.post['uid'] }}" class="post-action-btn">
2026-05-10 09:08:12 +02:00
&#x1F4AC; {{ item.comment_count }}
</a>
2026-05-11 20:49:45 +02:00
<a href="/posts/{{ item.post['slug'] or item.post['uid'] }}" class="post-action-btn share">
2026-05-10 09:08:12 +02:00
&#x2197;&#xFE0E; Open
</a>
<button class="post-action-btn">&#x1F517; Share</button>
</div>
2026-05-11 07:02:06 +02:00
{% if user %}
<form class="feed-comment-form" method="POST" action="/comments/create">
<input type="hidden" name="post_uid" value="{{ item.post['uid'] }}">
2026-05-12 15:07:34 +02:00
<img src="{{ avatar_url('multiavatar', user['username'], 24) }}" class="avatar-img avatar-24" alt="" loading="lazy">
2026-05-11 07:02:06 +02:00
<input type="text" name="content" placeholder="Your opinion goes here..." maxlength="1000" autocomplete="off">
<button type="submit" class="feed-comment-submit">Post</button>
</form>
{% endif %}
2026-05-10 09:08:12 +02:00
</article>
{% else %}
2026-05-10 21:33:53 +02:00
<div class="empty-state">No posts yet. Be the first!</div>
2026-05-10 09:08:12 +02:00
{% endfor %}
</div>
2026-05-11 03:14:43 +02:00
{% if next_cursor %}
2026-05-12 15:07:34 +02:00
<div class="load-more-wrap">
<a href="/feed?before={{ next_cursor }}{% if current_tab %}&tab={{ current_tab }}{% endif %}{% if current_topic %}&topic={{ current_topic }}{% endif %}" class="btn btn-secondary btn-sm"><span class="icon">&#x1F4C4;</span>Load More</a>
2026-05-11 03:14:43 +02:00
</div>
{% endif %}
2026-05-10 09:08:12 +02:00
</div>
<aside class="feed-right">
<div class="daily-topic-card">
<div class="daily-topic-label">Daily Topic</div>
2026-05-11 00:41:41 +02:00
<h4>{{ daily_topic.get('title', '') }}</h4>
<p>{{ daily_topic.get('summary', '') }}</p>
2026-05-10 09:08:12 +02:00
<div class="topic-links">
2026-05-12 15:07:34 +02:00
<a href="/news/{{ daily_topic.get('slug', '') }}">Read More</a>
{% if daily_topic.get('url', '') %}
<a href="{{ daily_topic['url'] }}" target="_blank" rel="noopener">Source</a>
{% endif %}
2026-05-10 09:08:12 +02:00
</div>
</div>
<div class="community-stats">
<h3>Community</h3>
<div class="stat-row">
<span class="label">Total Members</span>
<span class="value">{{ total_members }}</span>
</div>
<div class="stat-row">
<span class="label">Posts Today</span>
<span class="value">{{ posts_today }}</span>
</div>
<div class="stat-row">
<span class="label">Total Projects</span>
<span class="value">{{ total_projects }}</span>
</div>
2026-05-12 15:07:34 +02:00
<div class="stat-row">
<span class="label">Total Gists</span>
<span class="value">{{ total_gists }}</span>
</div>
<div class="top-authors-section">
<h3 class="top-authors-title">Top Authors</h3>
2026-05-10 09:08:12 +02:00
{% for author in top_authors %}
<div class="stat-row">
<span class="label">
2026-05-11 05:30:51 +02:00
<a href="/profile/{{ author['username'] }}">
2026-05-12 15:07:34 +02:00
<img src="{{ avatar_url('multiavatar', author['username'], 20) }}" class="avatar-img avatar-xs" alt="{{ author['username'] }}" loading="lazy">
2026-05-11 05:30:51 +02:00
{{ author['username'] }}</a>
2026-05-10 09:08:12 +02:00
</span>
<span class="value">{{ author.get('stars', 0) }}</span>
</div>
2026-05-11 05:30:51 +02:00
{% else %}
2026-05-12 15:07:34 +02:00
<div class="no-authors-msg">No top authors yet</div>
2026-05-10 09:08:12 +02:00
{% endfor %}
</div>
</div>
</aside>
</div>
2026-05-12 12:45:52 +02:00
{% if user %}
2026-05-10 09:08:12 +02:00
<a href="#" class="feed-fab" data-modal="create-post-modal" title="Create New Post">+</a>
2026-05-11 05:30:51 +02:00
<div class="modal-overlay" id="create-post-modal">
2026-05-12 15:07:34 +02:00
<div class="card modal-card">
<div class="modal-header">
<h3>Create New Post</h3>
<button type="button" class="modal-close btn-ghost btn-icon modal-close-btn">&times;</button>
2026-05-10 09:08:12 +02:00
</div>
<form id="create-post-form" method="POST" action="/posts/create" enctype="multipart/form-data">
2026-05-12 15:07:34 +02:00
<div class="form-row">
{% for t in TOPICS %}
<label class="topic-label">
<input type="radio" name="topic" value="{{ t }}" {% if t == 'random' %}checked{% endif %} class="topic-radio">
2026-05-10 09:08:12 +02:00
{{ t|capitalize }}
</label>
{% endfor %}
</div>
2026-05-12 15:07:34 +02:00
<div class="auth-field auth-field-gap">
2026-05-10 09:08:12 +02:00
<label for="post-content">What are you sharing?</label>
2026-05-12 15:07:34 +02:00
<textarea id="post-content" name="content" required maxlength="2000" placeholder="What's on your mind?" class="min-h-120" data-mention></textarea>
2026-05-11 05:30:51 +02:00
<small class="hint-text"><span id="post-content-count">0/2000</span></small>
2026-05-10 09:08:12 +02:00
</div>
2026-05-12 15:07:34 +02:00
<div class="auth-field auth-field-gap">
2026-05-10 09:08:12 +02:00
<label for="post-title">Title (optional)</label>
<input type="text" id="post-title" name="title" maxlength="500" placeholder="Post title">
2026-05-11 05:30:51 +02:00
<small class="hint-text"><span id="post-title-count">0/500</span></small>
2026-05-10 09:08:12 +02:00
</div>
2026-05-13 21:17:57 +02:00
<div class="auth-field auth-field-gap">
<label for="project_uid">Link to Project (Optional)</label>
<select id="project_uid" name="project_uid">
<option value="">No project</option>
{% for p in get_user_projects(user['uid']) %}
<option value="{{ p['uid'] }}">{{ p['title'] }}</option>
{% endfor %}
</select>
</div>
<div class="auth-field auth-field-gap">
<label for="post-image">Add an image (optional)</label>
<input type="file" id="post-image" name="image" accept="image/*">
</div>
2026-05-10 09:08:12 +02:00
2026-05-12 15:07:34 +02:00
<div class="modal-footer">
2026-05-10 09:08:12 +02:00
<button type="button" class="modal-close btn btn-secondary">Cancel</button>
<button type="submit" class="btn btn-primary">Post</button>
</div>
</form>
</div>
</div>
2026-05-12 12:45:52 +02:00
{% endif %}
2026-05-10 09:08:12 +02:00
{% endblock %}