From 45e9030c1d3b87b0962eafa54306d663addf1e9c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Z=C3=B6ller?=
Date: Wed, 3 Dec 2025 07:18:43 +0100
Subject: [PATCH] Moar federation
---
.../fitpub/controller/ActivityController.java | 51 ++++++++++++++-----
.../templates/activities/detail.html | 12 +++--
2 files changed, 46 insertions(+), 17 deletions(-)
diff --git a/src/main/java/org/operaton/fitpub/controller/ActivityController.java b/src/main/java/org/operaton/fitpub/controller/ActivityController.java
index f1c62aa..a43b28b 100644
--- a/src/main/java/org/operaton/fitpub/controller/ActivityController.java
+++ b/src/main/java/org/operaton/fitpub/controller/ActivityController.java
@@ -136,49 +136,72 @@ public class ActivityController {
/**
* Format activity content for ActivityPub.
+ * Uses plain text with Unicode symbols for maximum compatibility across Fediverse platforms.
*/
private String formatActivityContent(Activity activity) {
StringBuilder content = new StringBuilder();
+ // Title (if present)
if (activity.getTitle() != null && !activity.getTitle().isEmpty()) {
- content.append("").append(escapeHtml(activity.getTitle())).append("
");
+ content.append(activity.getTitle()).append("\n\n");
}
+ // Description (if present)
if (activity.getDescription() != null && !activity.getDescription().isEmpty()) {
- content.append("").append(escapeHtml(activity.getDescription())).append("
");
+ content.append(activity.getDescription()).append("\n\n");
}
- content.append("");
- content.append("Activity Type: ").append(activity.getActivityType()).append("
");
+ // Activity type with emoji
+ String activityEmoji = getActivityEmoji(activity.getActivityType());
+ content.append(activityEmoji).append(" ").append(activity.getActivityType());
+ // Metrics on separate lines
if (activity.getTotalDistance() != null) {
- content.append("Distance: ")
- .append(String.format("%.2f km", activity.getTotalDistance().doubleValue() / 1000.0))
- .append("
");
+ content.append("\nπ ")
+ .append(String.format("%.2f km", activity.getTotalDistance().doubleValue() / 1000.0));
}
if (activity.getTotalDurationSeconds() != null) {
long hours = activity.getTotalDurationSeconds() / 3600;
long minutes = (activity.getTotalDurationSeconds() % 3600) / 60;
long seconds = activity.getTotalDurationSeconds() % 60;
- content.append("Duration: ");
+ content.append("\nβ±οΈ ");
if (hours > 0) {
content.append(hours).append("h ");
}
- content.append(minutes).append("m ").append(seconds).append("s
");
+ content.append(minutes).append("m ").append(seconds).append("s");
}
if (activity.getElevationGain() != null) {
- content.append("Elevation Gain: ")
- .append(String.format("%.0f m", activity.getElevationGain()))
- .append("
");
+ content.append("\nβ°οΈ ")
+ .append(String.format("%.0f m", activity.getElevationGain()));
}
- content.append("
");
-
return content.toString();
}
+ /**
+ * Get an emoji for the activity type.
+ */
+ private String getActivityEmoji(Activity.ActivityType type) {
+ return switch (type) {
+ case RUN -> "π";
+ case RIDE -> "π΄";
+ case HIKE -> "π₯Ύ";
+ case WALK -> "πΆ";
+ case SWIM -> "π";
+ case ALPINE_SKI, BACKCOUNTRY_SKI, NORDIC_SKI -> "β·οΈ";
+ case SNOWBOARD -> "π";
+ case ROWING -> "π£";
+ case KAYAKING, CANOEING -> "πΆ";
+ case INLINE_SKATING -> "βΈοΈ";
+ case ROCK_CLIMBING, MOUNTAINEERING -> "π§";
+ case YOGA -> "π§";
+ case WORKOUT -> "πͺ";
+ default -> "ποΈ";
+ };
+ }
+
/**
* Simple HTML escaping.
*/
diff --git a/src/main/resources/templates/activities/detail.html b/src/main/resources/templates/activities/detail.html
index 6b7bf36..9cbe903 100644
--- a/src/main/resources/templates/activities/detail.html
+++ b/src/main/resources/templates/activities/detail.html
@@ -45,7 +45,7 @@
-
+
Edit
@@ -315,8 +315,14 @@
document.getElementById('activityDescription').style.display = 'none';
}
- // Edit button
- document.getElementById('editBtn').href = `/activities/${activity.id}/edit`;
+ // Show Edit/Delete buttons only if user is logged in and owns the activity
+ if (FitPubAuth.isAuthenticated()) {
+ const currentUser = FitPubAuth.getCurrentUser();
+ if (currentUser && currentUser.id === activity.userId) {
+ document.getElementById('activityActions').style.display = 'block';
+ document.getElementById('editBtn').href = `/activities/${activity.id}/edit`;
+ }
+ }
// Metrics
document.getElementById('metricDistance').textContent = formatDistance(activity.totalDistance);