src/main/kotlin/de/uapcore/lightpit/servlet/FeedServlet.kt

changeset 242
b7f3e972b13c
parent 241
1ca4f27cefe8
child 254
55ca6cafc3dd
--- a/src/main/kotlin/de/uapcore/lightpit/servlet/FeedServlet.kt	Sat Nov 27 12:12:20 2021 +0100
+++ b/src/main/kotlin/de/uapcore/lightpit/servlet/FeedServlet.kt	Sat Nov 27 13:03:57 2021 +0100
@@ -30,8 +30,10 @@
 import de.uapcore.lightpit.AbstractServlet
 import de.uapcore.lightpit.HttpRequest
 import de.uapcore.lightpit.dao.DataAccessObject
-import de.uapcore.lightpit.entities.IssueHistoryData
+import de.uapcore.lightpit.entities.IssueCommentHistoryEntry
 import de.uapcore.lightpit.entities.IssueHistoryEntry
+import de.uapcore.lightpit.types.IssueHistoryType
+import de.uapcore.lightpit.viewmodel.CommentDiff
 import de.uapcore.lightpit.viewmodel.IssueDiff
 import de.uapcore.lightpit.viewmodel.IssueFeed
 import de.uapcore.lightpit.viewmodel.IssueFeedEntry
@@ -46,8 +48,36 @@
         get("/%project/issues.rss", this::issues)
     }
 
-    private fun fullContent(issue: IssueHistoryData) = IssueDiff(
-        issue.id,
+    val diffGenerator by lazyOf(DiffRowGenerator.create()
+        .showInlineDiffs(true)
+        .mergeOriginalRevised(true)
+        .inlineDiffByWord(true)
+        .oldTag { start -> if (start) "<strike style=\"color:red\">" else "</strike>" }
+        .newTag { start -> if (start) "<i style=\"color: green\">" else "</i>" }
+        .build()
+    )
+
+    private fun fullContent(data: IssueCommentHistoryEntry) =
+        CommentDiff(
+            data.issueid,
+            data.commentid,
+            data.subject,
+            data.comment.replace("\r", "")
+        )
+
+    private fun diffContent(cur: IssueCommentHistoryEntry, next: IssueCommentHistoryEntry) =
+        CommentDiff(
+            cur.issueid,
+            cur.commentid,
+            cur.subject,
+            diffGenerator.generateDiffRows(
+                next.comment.replace("\r", "").split('\n'),
+                cur.comment.replace("\r", "").split('\n')
+            ).joinToString("\n", transform = DiffRow::getOldLine)
+        )
+
+    private fun fullContent(issue: IssueHistoryEntry) = IssueDiff(
+        issue.issueid,
         issue.subject,
         issue.component,
         issue.status.name,
@@ -60,19 +90,10 @@
         issue.resolved
     )
 
-    private fun diffContent(cur: IssueHistoryData, next: IssueHistoryData): IssueDiff {
-        val generator = DiffRowGenerator.create()
-            .showInlineDiffs(true)
-            .mergeOriginalRevised(true)
-            .inlineDiffByWord(true)
-            .oldTag { start -> if (start) "<strike style=\"color:red\">" else "</strike>" }
-            .newTag { start -> if (start) "<i style=\"color: green\">" else "</i>" }
-            .build()
-
+    private fun diffContent(cur: IssueHistoryEntry, next: IssueHistoryEntry): IssueDiff {
         val prev = fullContent(next)
         val diff = fullContent(cur)
-
-        val result = generator.generateDiffRows(
+        val result = diffGenerator.generateDiffRows(
             listOf(
                 prev.subject, prev.component, prev.status,
                 prev.category, prev.assignee, prev.eta, prev.affected, prev.resolved
@@ -92,7 +113,7 @@
         diff.affected = result[6].oldLine
         diff.resolved = result[7].oldLine
 
-        diff.description = generator.generateDiffRows(
+        diff.description = diffGenerator.generateDiffRows(
             prev.description.split('\n'),
             diff.description.split('\n')
         ).joinToString("\n", transform = DiffRow::getOldLine)
@@ -102,21 +123,42 @@
 
     /**
      * Generates the feed entries.
-     * Assumes that [historyEntry] is already sorted by timestamp (descending).
+     * Assumes that [issueEntries] and [commentEntries] are already sorted by timestamp (descending).
      */
-    private fun generateFeedEntries(historyEntry: List<IssueHistoryEntry>): List<IssueFeedEntry> =
-        if (historyEntry.isEmpty()) {
+    private fun generateFeedEntries(
+        issueEntries: List<IssueHistoryEntry>,
+        commentEntries: List<IssueCommentHistoryEntry>
+    ): List<IssueFeedEntry> =
+        (generateIssueFeedEntries(issueEntries) + generateCommentFeedEntries(commentEntries)).sortedByDescending { it.time }
+
+    private fun generateIssueFeedEntries(entries: List<IssueHistoryEntry>): List<IssueFeedEntry> =
+        if (entries.isEmpty()) {
             emptyList()
         } else {
-            historyEntry.groupBy { it.data.id }.mapValues { (_, history) ->
+            entries.groupBy { it.issueid }.mapValues { (_, history) ->
                 history.zipWithNext().map { (cur, next) ->
                     IssueFeedEntry(
-                        cur.time, cur.type, diffContent(cur.data, next.data)
+                        cur.time, cur.type, issue = diffContent(cur, next)
                     )
                 }.plus(
-                    history.last().let { IssueFeedEntry(it.time, it.type, fullContent(it.data)) }
+                    history.last().let { IssueFeedEntry(it.time, it.type, issue = fullContent(it)) }
                 )
-            }.flatMap { it.value }.sortedByDescending { it.time }
+            }.flatMap { it.value }
+        }
+
+    private fun generateCommentFeedEntries(entries: List<IssueCommentHistoryEntry>): List<IssueFeedEntry> =
+        if (entries.isEmpty()) {
+            emptyList()
+        } else {
+            entries.groupBy { it.commentid }.mapValues { (_, history) ->
+                history.zipWithNext().map { (cur, next) ->
+                    IssueFeedEntry(
+                        cur.time, cur.type, comment = diffContent(cur, next)
+                    )
+                }.plus(
+                    history.last().let { IssueFeedEntry(it.time, it.type, comment = fullContent(it)) }
+                )
+            }.flatMap { it.value }
         }
 
     private fun issues(http: HttpRequest, dao: DataAccessObject) {
@@ -126,6 +168,7 @@
             return
         }
         val assignees = http.param("assignee")?.split(',')
+        val comments = http.param("comments") ?: "all"
 
         val days = http.param("days")?.toIntOrNull() ?: 30
 
@@ -133,9 +176,14 @@
         val issueHistory = if (assignees == null) issuesFromDb else
             issuesFromDb.filter { assignees.contains(it.currentAssignee) }
 
-        // TODO: add comment history depending on parameter
+        val commentsFromDb = dao.listIssueCommentHistory(project.id, days)
+        val commentHistory = when (comments) {
+            "all" -> commentsFromDb
+            "new" -> commentsFromDb.filter { it.type == IssueHistoryType.NewComment }
+            else -> emptyList()
+        }
 
-        http.view = IssueFeed(project, generateFeedEntries(issueHistory))
+        http.view = IssueFeed(project, generateFeedEntries(issueHistory, commentHistory))
         http.renderFeed("issues-feed")
     }
 }
\ No newline at end of file

mercurial