Better Post Formatting
This commit is contained in:
parent
f92db29b0a
commit
3cba6de9f1
2 changed files with 46 additions and 43 deletions
|
|
@ -291,52 +291,64 @@ public class ActivityPubController {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format activity content for ActivityPub.
|
* Format activity content as HTML for ActivityPub.
|
||||||
* Uses plain text with Unicode symbols for maximum compatibility.
|
* Mastodon and most Fediverse software expect HTML in the content field.
|
||||||
*/
|
*/
|
||||||
private String formatActivityContent(Activity activity) {
|
private String formatActivityContent(Activity activity) {
|
||||||
StringBuilder content = new StringBuilder();
|
StringBuilder content = new StringBuilder();
|
||||||
|
|
||||||
// Title (if present)
|
// Title
|
||||||
if (activity.getTitle() != null && !activity.getTitle().isEmpty()) {
|
if (activity.getTitle() != null && !activity.getTitle().isEmpty()) {
|
||||||
content.append(activity.getTitle()).append("\n\n");
|
content.append("<p><strong>").append(escapeHtml(activity.getTitle())).append("</strong></p>");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Description (if present)
|
// Description
|
||||||
if (activity.getDescription() != null && !activity.getDescription().isEmpty()) {
|
if (activity.getDescription() != null && !activity.getDescription().isEmpty()) {
|
||||||
content.append(activity.getDescription()).append("\n\n");
|
content.append("<p>").append(escapeHtml(activity.getDescription())).append("</p>");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Activity type with emoji
|
// Activity type with emoji
|
||||||
String activityEmoji = getActivityEmoji(activity.getActivityType());
|
String activityEmoji = getActivityEmoji(activity.getActivityType());
|
||||||
String formattedType = ActivityFormatter.formatActivityType(activity.getActivityType());
|
String formattedType = ActivityFormatter.formatActivityType(activity.getActivityType());
|
||||||
content.append(activityEmoji).append(" ").append(formattedType);
|
content.append("<p>").append(activityEmoji).append(" ").append(escapeHtml(formattedType)).append("</p>");
|
||||||
|
|
||||||
// Metrics
|
// Metrics
|
||||||
|
StringBuilder metrics = new StringBuilder();
|
||||||
if (activity.getTotalDistance() != null) {
|
if (activity.getTotalDistance() != null) {
|
||||||
content.append("\n📏 ")
|
metrics.append("📏 ")
|
||||||
.append(String.format("%.2f km", activity.getTotalDistance().doubleValue() / 1000.0));
|
.append(String.format("%.2f km", activity.getTotalDistance().doubleValue() / 1000.0))
|
||||||
|
.append("<br>");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activity.getTotalDurationSeconds() != null) {
|
if (activity.getTotalDurationSeconds() != null) {
|
||||||
long hours = activity.getTotalDurationSeconds() / 3600;
|
long hours = activity.getTotalDurationSeconds() / 3600;
|
||||||
long minutes = (activity.getTotalDurationSeconds() % 3600) / 60;
|
long minutes = (activity.getTotalDurationSeconds() % 3600) / 60;
|
||||||
long seconds = activity.getTotalDurationSeconds() % 60;
|
long seconds = activity.getTotalDurationSeconds() % 60;
|
||||||
content.append("\n⏱️ ");
|
metrics.append("⏱️ ");
|
||||||
if (hours > 0) {
|
if (hours > 0) {
|
||||||
content.append(hours).append("h ");
|
metrics.append(hours).append("h ");
|
||||||
}
|
}
|
||||||
content.append(minutes).append("m ").append(seconds).append("s");
|
metrics.append(minutes).append("m ").append(seconds).append("s").append("<br>");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activity.getElevationGain() != null) {
|
if (activity.getElevationGain() != null) {
|
||||||
content.append("\n⛰️ ")
|
metrics.append("⛰️ ")
|
||||||
.append(String.format("%.0f m", activity.getElevationGain().doubleValue()));
|
.append(String.format("%.0f m", activity.getElevationGain().doubleValue()))
|
||||||
|
.append("<br>");
|
||||||
|
}
|
||||||
|
if (metrics.length() > 0) {
|
||||||
|
content.append("<p>").append(metrics).append("</p>");
|
||||||
}
|
}
|
||||||
|
|
||||||
return content.toString();
|
return content.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String escapeHtml(String text) {
|
||||||
|
if (text == null) return "";
|
||||||
|
return text.replace("&", "&")
|
||||||
|
.replace("<", "<")
|
||||||
|
.replace(">", ">")
|
||||||
|
.replace("\"", """);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get emoji for activity type.
|
* Get emoji for activity type.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -216,47 +216,33 @@ public class ActivityPostProcessingService {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format activity content for ActivityPub Note.
|
* Format activity content as HTML for ActivityPub Note.
|
||||||
* Uses plain text with Unicode symbols for maximum compatibility across Fediverse platforms.
|
* Mastodon and most Fediverse software expect HTML in the content field.
|
||||||
*
|
|
||||||
* Format:
|
|
||||||
* - Title (if present)
|
|
||||||
* - Description (if present)
|
|
||||||
* - Activity type with emoji
|
|
||||||
* - Distance (if present)
|
|
||||||
* - Duration (if present)
|
|
||||||
* - Elevation gain (if present)
|
|
||||||
*
|
*
|
||||||
* @param activity the activity to format
|
* @param activity the activity to format
|
||||||
* @return formatted content string
|
* @return formatted HTML content string
|
||||||
*/
|
*/
|
||||||
private String formatActivityContent(Activity activity) {
|
private String formatActivityContent(Activity activity) {
|
||||||
StringBuilder content = new StringBuilder();
|
StringBuilder content = new StringBuilder();
|
||||||
|
|
||||||
// Title (if present)
|
|
||||||
if (activity.getTitle() != null && !activity.getTitle().isEmpty()) {
|
if (activity.getTitle() != null && !activity.getTitle().isEmpty()) {
|
||||||
content.append(activity.getTitle()).append("\n\n");
|
content.append("<p><strong>").append(escapeHtml(activity.getTitle())).append("</strong></p>");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Description (if present)
|
|
||||||
if (activity.getDescription() != null && !activity.getDescription().isEmpty()) {
|
if (activity.getDescription() != null && !activity.getDescription().isEmpty()) {
|
||||||
content.append(activity.getDescription()).append("\n\n");
|
content.append("<p>").append(escapeHtml(activity.getDescription())).append("</p>");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Activity type with emoji
|
|
||||||
String activityEmoji = getActivityEmoji(activity.getActivityType());
|
String activityEmoji = getActivityEmoji(activity.getActivityType());
|
||||||
String formattedType = ActivityFormatter.formatActivityType(activity.getActivityType());
|
String formattedType = ActivityFormatter.formatActivityType(activity.getActivityType());
|
||||||
content.append(activityEmoji).append(" ").append(formattedType);
|
content.append("<p>").append(activityEmoji).append(" ").append(escapeHtml(formattedType)).append("</p>");
|
||||||
|
|
||||||
// Metrics, each on its own line with a blank line separating from above
|
|
||||||
StringBuilder metrics = new StringBuilder();
|
StringBuilder metrics = new StringBuilder();
|
||||||
|
|
||||||
if (activity.getTotalDistance() != null) {
|
if (activity.getTotalDistance() != null) {
|
||||||
metrics.append("📏 ")
|
metrics.append("📏 ")
|
||||||
.append(String.format("%.2f km", activity.getTotalDistance().doubleValue() / 1000.0))
|
.append(String.format("%.2f km", activity.getTotalDistance().doubleValue() / 1000.0))
|
||||||
.append("\n");
|
.append("<br>");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activity.getTotalDurationSeconds() != null) {
|
if (activity.getTotalDurationSeconds() != null) {
|
||||||
long hours = activity.getTotalDurationSeconds() / 3600;
|
long hours = activity.getTotalDurationSeconds() / 3600;
|
||||||
long minutes = (activity.getTotalDurationSeconds() % 3600) / 60;
|
long minutes = (activity.getTotalDurationSeconds() % 3600) / 60;
|
||||||
|
|
@ -265,23 +251,28 @@ public class ActivityPostProcessingService {
|
||||||
if (hours > 0) {
|
if (hours > 0) {
|
||||||
metrics.append(hours).append("h ");
|
metrics.append(hours).append("h ");
|
||||||
}
|
}
|
||||||
metrics.append(minutes).append("m ").append(seconds).append("s")
|
metrics.append(minutes).append("m ").append(seconds).append("s").append("<br>");
|
||||||
.append("\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activity.getElevationGain() != null) {
|
if (activity.getElevationGain() != null) {
|
||||||
metrics.append("⛰️ ")
|
metrics.append("⛰️ ")
|
||||||
.append(String.format("%.0f m", activity.getElevationGain()))
|
.append(String.format("%.0f m", activity.getElevationGain()))
|
||||||
.append("\n");
|
.append("<br>");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (metrics.length() > 0) {
|
if (metrics.length() > 0) {
|
||||||
content.append("\n\n").append(metrics.toString().stripTrailing());
|
content.append("<p>").append(metrics).append("</p>");
|
||||||
}
|
}
|
||||||
|
|
||||||
return content.toString();
|
return content.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String escapeHtml(String text) {
|
||||||
|
if (text == null) return "";
|
||||||
|
return text.replace("&", "&")
|
||||||
|
.replace("<", "<")
|
||||||
|
.replace(">", ">")
|
||||||
|
.replace("\"", """);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an emoji for the activity type.
|
* Get an emoji for the activity type.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue