feat(mastodon): Add support for server announcements

Implemented a new 'Announcements' buffer to view instance-wide news. Features include:

- New buffer and UI panel for announcements.

- Support for templates and rendering of announcement content.

- 'Dismiss' functionality (mapped to Enter/Return) to mark announcements as read.

- Integrated into account settings for buffer management.
This commit is contained in:
2026-01-12 01:53:03 -06:00
parent 4df58f0880
commit 15a9df2ca9
10 changed files with 240 additions and 3 deletions

View File

@@ -84,4 +84,10 @@ def compose_notification(notification, db, settings, relative_times, show_screen
filtered = utils.evaluate_filters(post=notification, current_context="notifications")
if filtered != None:
text = _("hidden by filter {}").format(filtered)
return [user, text, ts]
return [user, text, ts]
def compose_announcement(announcement, db, settings, relative_times, show_screen_names, safe=False):
# Use the default template or a configured one if available
template = settings.get("templates", {}).get("announcement", templates.announcement_default_template)
text = templates.render_announcement(announcement, template, settings, relative_times, db["utc_offset"])
return [text]

View File

@@ -13,12 +13,14 @@ post_variables = ["date", "display_name", "screen_name", "source", "lang", "safe
person_variables = ["display_name", "screen_name", "description", "followers", "following", "favorites", "posts", "created_at"]
conversation_variables = ["users", "last_post"]
notification_variables = ["display_name", "screen_name", "text", "date"]
announcement_variables = ["text", "published_at", "updated_at", "starts_at", "ends_at", "read"]
# Default, translatable templates.
post_default_template = _("$display_name, $text $image_descriptions $date. $source")
dm_sent_default_template = _("Dm to $recipient_display_name, $text $date")
person_default_template = _("$display_name (@$screen_name). $followers followers, $following following, $posts posts. Joined $created_at.")
notification_default_template = _("$display_name $text, $date")
announcement_default_template = _("$text. Published $published_at. $read")
def process_date(field, relative_times=True, offset_hours=0):
original_date = arrow.get(field)
@@ -185,3 +187,23 @@ def render_notification(notification, template, post_template, settings, relativ
result = Template(_(template)).safe_substitute(**available_data)
result = result.replace(" . ", "")
return result
def render_announcement(announcement, template, settings, relative_times=False, offset_hours=0):
""" Renders any given announcement according to the passed template. """
global announcement_variables
available_data = dict()
# Process dates
for date_field in ["published_at", "updated_at", "starts_at", "ends_at"]:
if hasattr(announcement, date_field) and getattr(announcement, date_field) is not None:
available_data[date_field] = process_date(getattr(announcement, date_field), relative_times, offset_hours)
else:
available_data[date_field] = ""
available_data["text"] = utils.html_filter(announcement.content)
if announcement.read:
available_data["read"] = _("Read")
else:
available_data["read"] = _("Unread")
result = Template(_(template)).safe_substitute(**available_data)
return result