diff --git a/tildes/scss/modules/_group.scss b/tildes/scss/modules/_group.scss
index 2765678..65cc666 100644
--- a/tildes/scss/modules/_group.scss
+++ b/tildes/scss/modules/_group.scss
@@ -2,29 +2,24 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
.group-list {
+ margin: 1rem 0;
+
+ ol {
+ margin-left: 1rem;
+ }
+
+ li {
+ text-indent: -1rem;
+ margin-left: 1rem;
+ }
+
.link-group {
font-weight: bold;
}
-
- .group-subscription {
- flex-direction: column;
- margin: 0;
- }
-
- .group-subscription-count {
- margin-bottom: 0.2rem;
- }
-
- @for $indent-level from 1 through 4 {
- tr.group-level-#{$indent-level} td:first-child {
- padding-left: #{$indent-level}rem;
- }
- }
}
-.group-list-description {
+.group-list-activity {
font-style: italic;
- margin-left: 1rem;
font-size: 0.6rem;
line-height: 0.8rem;
}
diff --git a/tildes/scss/themes/_theme_base.scss b/tildes/scss/themes/_theme_base.scss
index 7b64d6b..de8bbd0 100644
--- a/tildes/scss/themes/_theme_base.scss
+++ b/tildes/scss/themes/_theme_base.scss
@@ -374,6 +374,12 @@
background-color: map-get($theme, "background-input");
}
+ .group-list-item-not-subscribed {
+ a.link-group {
+ color: map-get($theme, "warning");
+ }
+ }
+
.input-group-addon {
background-color: map-get($theme, "background-secondary");
color: map-get($theme, "foreground-highlight");
@@ -482,6 +488,10 @@
color: map-get($theme, "error");
}
+ .text-link {
+ color: map-get($theme, "link");
+ }
+
.text-secondary {
color: map-get($theme, "foreground-secondary");
}
diff --git a/tildes/tildes/templates/groups.jinja2 b/tildes/tildes/templates/groups.jinja2
index 414f599..8aa4eb9 100644
--- a/tildes/tildes/templates/groups.jinja2
+++ b/tildes/tildes/templates/groups.jinja2
@@ -5,6 +5,7 @@
{% from 'macros/groups.jinja2' import render_group_subscription_box with context %}
{% from 'macros/links.jinja2' import link_to_group with context %}
+{% from 'macros/utils.jinja2' import pluralize %}
{% block title %}Browse groups{% endblock %}
@@ -13,25 +14,49 @@
{% endblock %}
{% block content %}
-
-
-
- | Group |
- Subscribe |
-
-
-
- {% for group in groups %}
-
- |
- {{ link_to_group(group) }}
- {% if group.short_description %}
- {{ group.short_description }}
- {% endif %}
- |
- {{ render_group_subscription_box(group) }} |
-
+{% if request.user %}
+ Group name colors: subscribed / not subscribed. You can change your subscription status to a group in its sidebar when you are viewing it directly.
+{% endif %}
+
+
+
+
+ {% for group in groups %}
+ {# nest a list if it's a sub-group #}
+ {% if loop.previtem and group.path|length > loop.previtem.path|length %}{% endif %}
+
+ {# check in this order so logged-out users get the "subscribed" style #}
+ {% if request.user and not group.user_subscribed %}
+ -
+ {% else %}
+
-
+ {% endif %}
+
+ {{ link_to_group(group) }}
+ {% if group.short_description %}
+ - {{ group.short_description }}
+ {% endif %}
+
+ {% if group.path in daily_topic_counts and group.path in daily_comment_counts %}
+
+ Approx. daily activity:
+ {{ pluralize(daily_topic_counts[group.path], "topic") }},
+ {{ pluralize(daily_comment_counts[group.path], "comment") }}
+
+ {% endif %}
+
+
+ {# close any nested lists #}
+ {% if loop.nextitem and group.path|length > loop.nextitem.path|length %}
+
+ {% elif not loop.nextitem %}
+ {% for _ in range(group.path|length - 1) %}
+
{% endfor %}
-
-
+ {% endif %}
+ {% endfor %}
+
+
+
+Activity numbers are based on posts in the group over the last week, and only update once per day, shortly after 00:00 UTC.
{% endblock %}
diff --git a/tildes/tildes/views/group.py b/tildes/tildes/views/group.py
index 39353a0..c9ee54a 100644
--- a/tildes/tildes/views/group.py
+++ b/tildes/tildes/views/group.py
@@ -6,6 +6,7 @@
from pyramid.request import Request
from pyramid.view import view_config
+from tildes.enums import GroupStatType
from tildes.models.group import Group
@@ -14,4 +15,32 @@ def get_list_groups(request: Request) -> dict:
"""Show a list of all groups."""
groups = request.query(Group).order_by(Group.path).all()
- return {"groups": groups}
+ # converting this to SQLAlchemy seems like way more trouble than it's worth
+ posting_stats = request.db_session.execute(
+ """
+ select path, stat, ceil(sum(value) / count(*))
+ from group_stats
+ left join groups using (group_id)
+ where period && tstzrange(now() - interval '7 days', now())
+ group by path, stat
+ order by path, stat;
+ """
+ ).fetchall()
+
+ daily_comment_counts = {
+ row[0]: int(row[2])
+ for row in posting_stats
+ if row[1] == GroupStatType.COMMENTS_POSTED.name
+ }
+
+ daily_topic_counts = {
+ row[0]: int(row[2])
+ for row in posting_stats
+ if row[1] == GroupStatType.TOPICS_POSTED.name
+ }
+
+ return {
+ "groups": groups,
+ "daily_comment_counts": daily_comment_counts,
+ "daily_topic_counts": daily_topic_counts,
+ }