feat(android): improve New Activity notification copy in TimeSafariNativeFetcher
Aggregate API rows into one notification with Starred Project Update(s) titles, plan names in typographic quotes, and "+ N more have been updated." for multiples. Stop emitting the empty-data "No Project Updates" fallback. Sync internal docs.
This commit is contained in:
@@ -325,44 +325,68 @@ public class TimeSafariNativeFetcher implements NativeNotificationContentFetcher
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display title for a plansLastUpdatedBetween row; prefers {@code plan.name}, else "Unnamed Project".
|
||||
*/
|
||||
private String extractProjectDisplayTitle(JsonObject item) {
|
||||
if (item.has("plan")) {
|
||||
JsonObject plan = item.getAsJsonObject("plan");
|
||||
if (plan.has("name") && !plan.get("name").isJsonNull()) {
|
||||
String name = plan.get("name").getAsString();
|
||||
if (name != null && !name.trim().isEmpty()) {
|
||||
return name.trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
return "Unnamed Project";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String extractJwtIdFromItem(JsonObject item) {
|
||||
if (item.has("plan")) {
|
||||
JsonObject plan = item.getAsJsonObject("plan");
|
||||
if (plan.has("jwtId") && !plan.get("jwtId").isJsonNull()) {
|
||||
return plan.get("jwtId").getAsString();
|
||||
}
|
||||
}
|
||||
if (item.has("jwtId") && !item.get("jwtId").isJsonNull()) {
|
||||
return item.get("jwtId").getAsString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<NotificationContent> parseApiResponse(String responseBody, FetchContext context) {
|
||||
List<NotificationContent> contents = new ArrayList<>();
|
||||
try {
|
||||
JsonObject root = JsonParser.parseString(responseBody).getAsJsonObject();
|
||||
JsonArray dataArray = root.has("data") ? root.getAsJsonArray("data") : null;
|
||||
if (dataArray != null) {
|
||||
for (int i = 0; i < dataArray.size(); i++) {
|
||||
JsonObject item = dataArray.get(i).getAsJsonObject();
|
||||
NotificationContent content = new NotificationContent();
|
||||
String planId = null;
|
||||
String jwtId = null;
|
||||
if (item.has("plan")) {
|
||||
JsonObject plan = item.getAsJsonObject("plan");
|
||||
if (plan.has("handleId")) planId = plan.get("handleId").getAsString();
|
||||
if (plan.has("jwtId")) jwtId = plan.get("jwtId").getAsString();
|
||||
}
|
||||
if (planId == null && item.has("planId")) planId = item.get("planId").getAsString();
|
||||
if (jwtId == null && item.has("jwtId")) jwtId = item.get("jwtId").getAsString();
|
||||
if (dataArray == null || dataArray.size() == 0) {
|
||||
return contents;
|
||||
}
|
||||
|
||||
content.setId("endorser_" + (jwtId != null ? jwtId : (System.currentTimeMillis() + "_" + i)));
|
||||
content.setTitle(planId != null ? "Update: " + planId.substring(Math.max(0, planId.length() - 8)) : "Project Update");
|
||||
content.setBody(planId != null ? "Plan " + planId.substring(Math.max(0, planId.length() - 12)) + " has been updated." : "A project you follow has been updated.");
|
||||
content.setScheduledTime(context.scheduledTime != null ? context.scheduledTime : (System.currentTimeMillis() + 3600000));
|
||||
content.setPriority("default");
|
||||
content.setSound(true);
|
||||
contents.add(content);
|
||||
}
|
||||
}
|
||||
if (contents.isEmpty()) {
|
||||
NotificationContent defaultContent = new NotificationContent();
|
||||
defaultContent.setId("endorser_no_updates_" + System.currentTimeMillis());
|
||||
defaultContent.setTitle("No Project Updates");
|
||||
defaultContent.setBody("No updates in your starred projects.");
|
||||
defaultContent.setScheduledTime(context.scheduledTime != null ? context.scheduledTime : (System.currentTimeMillis() + 3600000));
|
||||
defaultContent.setPriority("default");
|
||||
defaultContent.setSound(true);
|
||||
contents.add(defaultContent);
|
||||
JsonObject firstItem = dataArray.get(0).getAsJsonObject();
|
||||
String firstTitle = extractProjectDisplayTitle(firstItem);
|
||||
String jwtId = extractJwtIdFromItem(firstItem);
|
||||
|
||||
NotificationContent content = new NotificationContent();
|
||||
content.setId("endorser_" + (jwtId != null ? jwtId : ("batch_" + System.currentTimeMillis())));
|
||||
int n = dataArray.size();
|
||||
String quotedFirst = "\u201C" + firstTitle + "\u201D";
|
||||
if (n == 1) {
|
||||
content.setTitle("Starred Project Update");
|
||||
content.setBody(quotedFirst + " has been updated.");
|
||||
} else {
|
||||
content.setTitle("Starred Project Updates");
|
||||
int more = n - 1;
|
||||
content.setBody(quotedFirst + " + " + more + " more have been updated.");
|
||||
}
|
||||
content.setScheduledTime(
|
||||
context.scheduledTime != null
|
||||
? context.scheduledTime
|
||||
: (System.currentTimeMillis() + 3600000));
|
||||
content.setPriority("default");
|
||||
content.setSound(true);
|
||||
contents.add(content);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Error parsing API response", e);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user