UX: display long PRs/Issues in an expandable excerpt (#471)

UX: display long PRs/Issues in an expandable excerpt (#471)

Note that this PR is also slightly changing github issues body position, and is using raw instead of text in the API call to get the raw body of the issue instead of a text only version.

This PR needs a companion PR in discourse core for the JS behavior: UX: moves from summary/details to a button to expand github body by jjaffeux · Pull Request #12698 · discourse/discourse · GitHub

diff --git a/lib/onebox/engine/github_issue_onebox.rb b/lib/onebox/engine/github_issue_onebox.rb
index 1c4a222..0bb26b7 100644
--- a/lib/onebox/engine/github_issue_onebox.rb
+++ b/lib/onebox/engine/github_issue_onebox.rb
@@ -1,5 +1,7 @@
 # frozen_string_literal: true
 
+require_relative '../mixins/github_body'
+
 module Onebox
   module Engine
     class GithubIssueOnebox
@@ -7,6 +9,7 @@ module Onebox
       include Engine
       include LayoutSupport
       include JSON
+      include Onebox::Mixins::GithubBody
 
       matches_regexp(/^https?:\/\/(?:www\.)?(?:(?:\w)+\.)?github\.com\/(?<org>.+)\/(?<repo>.+)\/issues\/([[:digit:]]+)/)
       always_https
@@ -23,32 +26,26 @@ module Onebox
       end
 
       def data
-        @raw ||= ::MultiJson.load(URI.open(url, "Accept" => "application/vnd.github.v3.text+json", read_timeout: timeout)) #custom Accept header so we can get body as text.
-        body_text = @raw["body_text"]
-
-        content_words = body_text.gsub("\n\n", "\n").gsub("\n", "<br>").split(" ") #one pass of removing double newline, then we change \n to <br> and later on we revert it back to \n this is a workaround to avoid losing newlines after we join it back.
-        max_words = 20
-        short_content =  content_words[0..max_words].join(" ")
-        short_content += "..." if content_words.length > max_words
-
-        created_at = Time.parse(@raw['created_at'])
-        closed_at = Time.parse(@raw['closed_at']) if @raw['closed_at']
-
+        created_at = Time.parse(raw['created_at'])
+        closed_at = Time.parse(raw['closed_at']) if raw['closed_at']
+        body, excerpt = compute_body(raw['body'])
         ulink = URI(link)
+
         {
           link: @url,
-          title: @raw["title"],
-          content: short_content.gsub("<br>", "\n"),
-          labels: @raw["labels"],
-          user: @raw['user'],
+          title: raw["title"],
+          body: body,
+          excerpt: excerpt,
+          labels: raw["labels"],
+          user: raw['user'],
           created_at: created_at.strftime("%I:%M%p - %d %b %y %Z"),
           created_at_date: created_at.strftime("%F"),
           created_at_time: created_at.strftime("%T"),
           closed_at: closed_at&.strftime("%I:%M%p - %d %b %y %Z"),
           closed_at_date: closed_at&.strftime("%F"),
           closed_at_time: closed_at&.strftime("%T"),
-          closed_by: @raw['closed_by'],
-          avatar: "https://avatars1.githubusercontent.com/u/#{@raw['user']['id']}?v=2&s=96",
+          closed_by: raw['closed_by'],
+          avatar: "https://avatars1.githubusercontent.com/u/#{raw['user']['id']}?v=2&s=96",
           domain: "#{ulink.host}/#{ulink.path.split('/')[1]}/#{ulink.path.split('/')[2]}",
         }
       end
diff --git a/lib/onebox/engine/github_pullrequest_onebox.rb b/lib/onebox/engine/github_pullrequest_onebox.rb
index 4b1ea11..090fdde 100644
--- a/lib/onebox/engine/github_pullrequest_onebox.rb
+++ b/lib/onebox/engine/github_pullrequest_onebox.rb
@@ -1,11 +1,14 @@
 # frozen_string_literal: true
 
+require_relative '../mixins/github_body'
+
 module Onebox
   module Engine
     class GithubPullRequestOnebox
       include Engine
       include LayoutSupport
       include JSON
+      include Onebox::Mixins::GithubBody
 
       GITHUB_COMMENT_REGEX = /(<!--.*?-->\r\n)/
 
@@ -34,8 +37,7 @@ module Onebox
         ulink = URI(link)
         result['domain'] = "#{ulink.host}/#{ulink.path.split('/')[1]}/#{ulink.path.split('/')[2]}"
 
-        body = (result['body'] || '').gsub(GITHUB_COMMENT_REGEX, '')
-        result['body'] = body.length > 0 ? body : nil
+        result['body'], result['excerpt'] = compute_body(result['body'])
 
         result
       end
diff --git a/lib/onebox/mixins/github_body.rb b/lib/onebox/mixins/github_body.rb
new file mode 100644
index 0000000..22ee13a
--- /dev/null
+++ b/lib/onebox/mixins/github_body.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+module Onebox
+  module Mixins
+    module GithubBody
+      def self.included(klass)
+        klass.include(Onebox::Engine)
+        klass.include(InstanceMethods)
+      end
+
+      module InstanceMethods
+        GITHUB_COMMENT_REGEX = /(<!--.*?-->\r\n)/
+        MAX_BODY_LENGTH = 80
+        def compute_body(body)
+          body = body.dup
+          excerpt = nil
+
+          body = (body || '').gsub(GITHUB_COMMENT_REGEX, '')
+          body = body.length > 0 ? body : nil
+          if body && body.length > MAX_BODY_LENGTH
+            excerpt = body[MAX_BODY_LENGTH..body.length].rstrip
+            body = body[0..MAX_BODY_LENGTH - 1]
+          end
+
+          [body, excerpt]
+        end
+      end
+    end
+  end
+end
diff --git a/lib/onebox/version.rb b/lib/onebox/version.rb
index 2a1d389..c9125a6 100644
--- a/lib/onebox/version.rb
+++ b/lib/onebox/version.rb
@@ -1,5 +1,5 @@
 # frozen_string_literal: true
 
 module Onebox
-  VERSION = "2.2.12"
+  VERSION = "2.2.13"
 end
diff --git a/templates/github/github_body.mustache b/templates/github/github_body.mustache
new file mode 100644
index 0000000..24c1ba6
--- /dev/null
+++ b/templates/github/github_body.mustache
@@ -0,0 +1,3 @@
+{{#body}}
+  <p class="github-body-container">{{body}}{{#excerpt}}<span class="show-more-container"><a href="{{html_url}}" target="_blank" rel="noopener" class="show-more">…</a>{{/excerpt}}</span>{{#excerpt}}<span class="excerpt hidden">{{excerpt}}</span>{{/excerpt}}</p>
+{{/body}}
diff --git a/templates/githubissue.mustache b/templates/githubissue.mustache
index c13e4f9..091669f 100644
--- a/templates/githubissue.mustache
+++ b/templates/githubissue.mustache
@@ -26,15 +26,13 @@
         </a>
       </div>
     </div>
-  </div>
-</div>
 
-<div class="github-row">
-  <p class='github-content'>{{content}}</p>
-</div>
+    {{> github/github_body}}
 
-<div class='labels'>
-  {{#labels}}
-    <span style="display:inline-block;margin-top:2px;background-color: #B8B8B8;padding: 2px;border-radius: 4px;color: #fff;margin-left: 3px;">{{name}}</span>
-  {{/labels}}
+    <div class='labels'>
+      {{#labels}}
+        <span style="display:inline-block;margin-top:2px;background-color: #B8B8B8;padding: 2px;border-radius: 4px;color: #fff;margin-left: 3px;">{{name}}</span>
+      {{/labels}}
+    </div>
+  </div>
 </div>
diff --git a/templates/githubpullrequest.mustache b/templates/githubpullrequest.mustache
index 8b95b6e..a4d731f 100644
--- a/templates/githubpullrequest.mustache
+++ b/templates/githubpullrequest.mustache
@@ -4,22 +4,9 @@
   </div>
 
   <div class="github-info-container">
-    {{^body}}
-      <h4>
-        <a href="{{html_url}}" target="_blank" rel="noopener">{{title}}</a>
-      </h4>
-    {{/body}}
-
-    {{#body}}
-      <details class="onebox-details">
-        <summary class="onebox-details-summary">
-          <h4>
-            <a href="{{html_url}}" target="_blank" rel="noopener">{{title}}</a>
-          </h4>
-        </summary>
-        <p class="onebox-details-body">{{body}}</p>
-      </details>
-    {{/body}}
+    <h4>
+      <a href="{{html_url}}" target="_blank" rel="noopener">{{title}}</a>
+    </h4>
 
     <div class="branches">
       <code>{{base.label}}</code> ← <code>{{head.label}}</code>
@@ -45,5 +32,6 @@
       </div>
     </div>
 
+    {{> github/github_body}}
   </div>
 </div>

GitHub sha: a713639f

1 Like

This commit appears in #471 which was approved by davidtaylorhq. It was merged by jjaffeux.