{% extends "document.njk" %} {% from "heading/macro.njk" import heading with context %} {% from "input/macro.njk" import input with context %} {% from "radios/macro.njk" import radios with context %} {% from "button/macro.njk" import button with context %} {% from "notification-banner/macro.njk" import notificationBanner with context %} {% block content %} {% if saved %} {{ notificationBanner({ type: "success", text: "Settings saved." }) }} {% endif %}
{# ─── Instance & Client API ──────────────────────────────────── #}
Instance & Client API

Settings reported to Mastodon-compatible clients (Phanpy, Elk, Moshidon).

{{ input({ name: "instanceLanguages", label: "Instance languages", hint: "Comma-separated ISO 639-1 codes (e.g. en,fr,de). Default: " + defaults.instanceLanguages | join(","), value: settings.instanceLanguages | join(","), type: "text" }) }} {{ input({ name: "maxCharacters", label: "Max characters per status", hint: "Character limit shown to clients. Default: " + defaults.maxCharacters, value: settings.maxCharacters, type: "number" }) }} {{ input({ name: "maxMediaAttachments", label: "Max media attachments", hint: "Per-status media file limit. Default: " + defaults.maxMediaAttachments, value: settings.maxMediaAttachments, type: "number" }) }} {{ radios({ name: "defaultVisibility", fieldset: { legend: "Default post visibility" }, hint: "Default visibility for new posts. Default: " + defaults.defaultVisibility, items: [ { value: "public", label: "Public" }, { value: "unlisted", label: "Unlisted" }, { value: "private", label: "Followers only" } ], values: [settings.defaultVisibility] }) }} {{ input({ name: "defaultLanguage", label: "Default post language", hint: "ISO 639-1 code (e.g. en, fr). Default: " + defaults.defaultLanguage, value: settings.defaultLanguage, type: "text" }) }}
{# ─── Federation & Delivery ──────────────────────────────────── #}
Federation & Delivery

Controls how content is stored, retained, and delivered to followers.

{{ input({ name: "timelineRetention", label: "Timeline retention (items)", hint: "Max items in the AP timeline. 0 = unlimited. Default: " + defaults.timelineRetention, value: settings.timelineRetention, type: "number" }) }} {{ input({ name: "notificationRetentionDays", label: "Notification retention (days)", hint: "Days to keep notifications. 0 = forever. Default: " + defaults.notificationRetentionDays, value: settings.notificationRetentionDays, type: "number" }) }} {{ input({ name: "activityRetentionDays", label: "Activity log retention (days)", hint: "Days to keep activity log entries. 0 = forever. Default: " + defaults.activityRetentionDays, value: settings.activityRetentionDays, type: "number" }) }} {{ input({ name: "replyChainDepth", label: "Reply chain depth", hint: "Max parent posts fetched for thread context. Default: " + defaults.replyChainDepth, value: settings.replyChainDepth, type: "number" }) }} {{ input({ name: "broadcastBatchSize", label: "Broadcast batch size", hint: "Followers per delivery batch. Default: " + defaults.broadcastBatchSize, value: settings.broadcastBatchSize, type: "number" }) }} {{ input({ name: "broadcastBatchDelay", label: "Broadcast batch delay (ms)", hint: "Delay between delivery batches in milliseconds. Default: " + defaults.broadcastBatchDelay, value: settings.broadcastBatchDelay, type: "number" }) }} {{ input({ name: "parallelWorkers", label: "Parallel delivery workers", hint: "Redis queue workers. 0 = in-process queue. Default: " + defaults.parallelWorkers, value: settings.parallelWorkers, type: "number" }) }} {{ radios({ name: "logLevel", fieldset: { legend: "Federation log level" }, hint: "Fedify log verbosity. Default: " + defaults.logLevel, items: [ { value: "debug", label: "Debug" }, { value: "info", label: "Info" }, { value: "warning", label: "Warning" }, { value: "error", label: "Error" } ], values: [settings.logLevel] }) }}
{# ─── Migration ──────────────────────────────────────────────── #}
Migration

Controls the speed of Mastodon account re-follow processing.

{{ input({ name: "refollowBatchSize", label: "Refollow batch size", hint: "Accounts per refollow batch. Default: " + defaults.refollowBatchSize, value: settings.refollowBatchSize, type: "number" }) }} {{ input({ name: "refollowDelay", label: "Refollow delay per follow (ms)", hint: "Delay between individual follow requests. Default: " + defaults.refollowDelay, value: settings.refollowDelay, type: "number" }) }} {{ input({ name: "refollowBatchDelay", label: "Refollow batch delay (ms)", hint: "Delay between refollow batches. Default: " + defaults.refollowBatchDelay, value: settings.refollowBatchDelay, type: "number" }) }}
{# ─── Security ───────────────────────────────────────────────── #}
Security {{ input({ name: "refreshTokenTtlDays", label: "Refresh token TTL (days)", hint: "Days before OAuth refresh tokens expire. Access tokens never expire. Default: " + defaults.refreshTokenTtlDays, value: settings.refreshTokenTtlDays, type: "number" }) }}
{{ button({ text: "Save settings" }) }}
{% endblock %}