refactor: rename Sources to OPML Sync, remove Manual type

- Remove 'Manual' source type (redundant with Blogs management)
- Rename 'Sources' to 'OPML Sync' for clarity
- Update labels to clarify URL syncs periodically, File is one-time import
- Fix date conversion in sources list controller

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Ricardo
2026-02-07 17:38:19 +01:00
parent 4a53f74bbc
commit 87ebebfb7a
4 changed files with 44 additions and 44 deletions

View File

@@ -20,7 +20,17 @@ async function list(request, response) {
const { application } = request.app.locals;
try {
const sources = await getSources(application);
const rawSources = await getSources(application);
// Convert Date objects to ISO strings for template date filter compatibility
const sources = rawSources.map((source) => ({
...source,
lastSyncAt: source.lastSyncAt
? (source.lastSyncAt instanceof Date
? source.lastSyncAt.toISOString()
: source.lastSyncAt)
: null,
}));
response.render("blogroll-sources", {
title: request.__("blogroll.sources.title"),
@@ -83,25 +93,19 @@ async function create(request, response) {
});
// Trigger initial sync for OPML sources
if (source.type === "opml_url" || source.type === "opml_file") {
try {
await syncOpmlSource(application, source);
request.session.messages = [
{ type: "success", content: request.__("blogroll.sources.created_synced") },
];
} catch (syncError) {
request.session.messages = [
{
type: "warning",
content: request.__("blogroll.sources.created_sync_failed", {
error: syncError.message,
}),
},
];
}
} else {
try {
await syncOpmlSource(application, source);
request.session.messages = [
{ type: "success", content: request.__("blogroll.sources.created") },
{ type: "success", content: request.__("blogroll.sources.created_synced") },
];
} catch (syncError) {
request.session.messages = [
{
type: "warning",
content: request.__("blogroll.sources.created_sync_failed", {
error: syncError.message,
}),
},
];
}

View File

@@ -32,30 +32,30 @@
},
"sources": {
"title": "Sources",
"manage": "Manage Sources",
"add": "Add Source",
"new": "New Source",
"edit": "Edit Source",
"create": "Create Source",
"save": "Save Source",
"empty": "No sources configured yet.",
"recent": "Recent Sources",
"title": "OPML Sync",
"manage": "OPML Sync",
"add": "Add OPML Source",
"new": "New OPML Source",
"edit": "Edit OPML Source",
"create": "Create",
"save": "Save",
"empty": "No OPML sources configured. Use this to bulk-import blogs from FreshRSS or other feed readers.",
"recent": "OPML Sources",
"interval": "Every %{minutes} min",
"lastSync": "Last synced",
"deleteConfirm": "Delete this source? Blogs imported from it will remain.",
"created": "Source created successfully.",
"created_synced": "Source created and synced successfully.",
"created_sync_failed": "Source created, but sync failed: %{error}",
"updated": "Source updated successfully.",
"deleted": "Source deleted successfully.",
"deleteConfirm": "Delete this OPML source? Blogs imported from it will remain.",
"created": "OPML source created successfully.",
"created_synced": "OPML source created and synced successfully.",
"created_sync_failed": "OPML source created, but sync failed: %{error}",
"updated": "OPML source updated successfully.",
"deleted": "OPML source deleted successfully.",
"synced": "Synced successfully. Added: %{added}, Updated: %{updated}",
"form": {
"name": "Name",
"type": "Type",
"typeHint": "How to import blogs from this source",
"type": "Import Type",
"typeHint": "URL syncs periodically, File is a one-time import",
"url": "OPML URL",
"urlHint": "URL of the OPML file to import",
"urlHint": "URL to your OPML file (e.g., FreshRSS export URL)",
"opmlContent": "OPML Content",
"opmlContentHint": "Paste the full OPML XML content here",
"syncInterval": "Sync Interval",

View File

@@ -1,6 +1,6 @@
{
"name": "@rmdes/indiekit-endpoint-blogroll",
"version": "1.0.4",
"version": "1.0.5",
"description": "Blogroll endpoint for Indiekit. Aggregates blog feeds from OPML, JSON feeds, or manual entry.",
"keywords": [
"indiekit",

View File

@@ -78,9 +78,8 @@
<div class="br-field">
<label for="type">{{ __("blogroll.sources.form.type") }}</label>
<select id="type" name="type" required onchange="toggleTypeFields()">
<option value="opml_url" {% if source.type == 'opml_url' %}selected{% endif %}>OPML URL</option>
<option value="opml_file" {% if source.type == 'opml_file' %}selected{% endif %}>OPML File (paste content)</option>
<option value="manual" {% if source.type == 'manual' %}selected{% endif %}>Manual (add blogs individually)</option>
<option value="opml_url" {% if source.type == 'opml_url' %}selected{% endif %}>OPML URL (auto-sync)</option>
<option value="opml_file" {% if source.type == 'opml_file' %}selected{% endif %}>OPML File (one-time import)</option>
</select>
<span class="br-field-hint">{{ __("blogroll.sources.form.typeHint") }}</span>
</div>
@@ -134,9 +133,6 @@ function toggleTypeFields() {
} else if (type === 'opml_file') {
urlField.style.display = 'none';
opmlContentField.style.display = 'flex';
} else {
urlField.style.display = 'none';
opmlContentField.style.display = 'none';
}
}